030 SSM综合练习06--数据后台管理系统--SSM权限操作及Spring Security入门

1.权限操作涉及的三张表

(1)用户表信息描述users

sql语句:

CREATE TABLE users (
    id VARCHAR2 ( 32 ) DEFAULT SYS_GUID () PRIMARY KEY,
    email VARCHAR2 ( 50 ) UNIQUE NOT NULL,
    username VARCHAR2 ( 50 ),
    PASSWORD VARCHAR2 ( 50 ),
    phoneNum VARCHAR2 ( 20 ),
STATUS INT 
)

(2)角色表描述role

sql语句:

CREATE TABLE role (
    id VARCHAR2 ( 32 ) DEFAULT SYS_GUID () PRIMARY KEY,
    roleName VARCHAR2 ( 50 ),
roleDesc VARCHAR2 ( 50 ) 
)

(3)权限资源表描述permission

sql语句:

CREATE TABLE permission (
    id VARCHAR2 ( 32 ) DEFAULT SYS_GUID () PRIMARY KEY,
    permissionName VARCHAR2 ( 50 ),
url VARCHAR2 ( 50 ) 
)

(4)权限资源与角色关联关系

权限资源与角色是多对多关系,我们使用role_permission表来描述。

sql语句:

CREATE TABLE role_permission (
    permissionId VARCHAR2 ( 32 ),
    roleId VARCHAR2 ( 32 ),
    PRIMARY KEY ( permissionId, roleId ),
    FOREIGN KEY ( permissionId ) REFERENCES permission ( id ),
FOREIGN KEY ( roleId ) REFERENCES role ( id ) 
)

(5)用户与角色关联关系

用户与角色之间是多对多关系,我们通过user_role表来描述其关联

sql语句:

CREATE TABLE users_role (
    userId VARCHAR2 ( 32 ),
    roleId VARCHAR2 ( 32 ),
    PRIMARY KEY ( userId, roleId ),
    FOREIGN KEY ( userId ) REFERENCES users ( id ),
FOREIGN KEY ( roleId ) REFERENCES role ( id ) 
)

(6)三张表关联

2.Spring Security概述

Spring Security是 Spring 项目组中用来提供安全认证服务的框架。 Spring Security 为基于J2EE企业应用软件提供了全面安全服务。
安全包括两个主要操作:
  “认证”,是为用户建立一个他所声明的主体。主题一般式指用户,设备或可以在你系 统中执行动作的其他系统 。典型范例:用户登录
  “授权”指的是一个用户能否在你的应用中执行某个操作,在到达授权判断之前,身份的主题已经由 身份验证过程建立了。

 

3.Spring Security简单应用---用户登录

(1)在父pom文件添加Spring Security的依赖

<dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>${spring.security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>${spring.security.version}</version>
        </dependency>

注意:${spring.security.version}为版本控制

 <properties>
        <spring.version>5.0.2.RELEASE</spring.version>
        <slf4j.version>1.6.6</slf4j.version>
        <log4j.version>1.2.12</log4j.version>
        <oracle.version>10.2.0.4.0</oracle.version>
        <mybatis.version>3.4.5</mybatis.version>
        <mysql.version>5.1.6</mysql.version>
        <spring.security.version>5.0.1.RELEASE</spring.security.version>
    </properties>

(2)在web.xml文件中配置springsecurity

<1>添加一个过滤器

<!--04 配置springSecurity(开始)-->
  <filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <!--04 配置springSecurity(结束)-->

<2>添加类加载路径

<!-- 配置加载类路径的配置文件 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml,classpath:spring-security.xml</param-value>
  </context-param>

(3)在resources目录下创建spring-security.xml文件,并设置其内容如下。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:security="http://www.springframework.org/schema/security"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security.xsd">

    <!-- 配置不拦截的资源 -->
    <security:http pattern="/login.jsp" security="none"/>
    <security:http pattern="/failer.jsp" security="none"/>
    <security:http pattern="/css/**" security="none"/>
    <security:http pattern="/img/**" security="none"/>
    <security:http pattern="/plugins/**" security="none"/>

    <!--
        配置具体的规则
        auto-config="true"    不用自己编写登录的页面,框架提供默认登录页面
        use-expressions="false"    是否使用SPEL表达式(没学习过)
    -->
    <security:http auto-config="true" use-expressions="false">
        <!-- 配置具体的拦截的规则 pattern="请求路径的规则" access="访问系统的人,必须有ROLE_USER的角色" -->
        <security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN"/>

        <!-- 定义跳转的具体的页面,login-page指定登录页面,login-processing-url登录路径,login.jsp文件中会调用 -->
        <!--authentication-success-forward-url指定成功页面,authentication-failure-url失败页面-->
        <security:form-login
                login-page="/login.jsp"
                login-processing-url="/login"
                default-target-url="/index.jsp"
                authentication-failure-url="/failer.jsp"
                authentication-success-forward-url="/pages/main.jsp"
        />

        <!-- 关闭跨域请求 -->
        <security:csrf disabled="true"/>

        <!-- 退出 -->
        <security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.jsp" />

    </security:http>

    <!-- 切换成数据库中的用户名和密码 -->
    <security:authentication-manager>
        <security:authentication-provider user-service-ref="userService">
            <!-- 配置加密的方式 -->
            <security:password-encoder ref="passwordEncoder"/>
        </security:authentication-provider>
    </security:authentication-manager>

    <!-- 配置加密类 -->
    <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

    <!-- 提供了入门的方式,在内存中存入用户名和密码
    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
    -->

</beans>

(5)在service模块中创建IUserService和UserServiceImpl

接口

package lucky.service;

import org.springframework.security.core.userdetails.UserDetailsService;

public interface IUserService extends UserDetailsService {
}

实现类

package lucky.service.impl;

import lucky.dao.IUserDao;
import lucky.domain.Role;
import lucky.domain.UserInfo;
import lucky.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 使用springsecurity进行用户登录
 */
@Service(value = "userService")
public class UserServiceImpl implements IUserService {
    @Autowired
    private IUserDao iUserDao;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserInfo userInfo=null;
        try {
            userInfo=iUserDao.queryByUsername(username);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //将自己的用户对象封装成UserDetails,参数1为用户名,参数2为密码,参数3是用户权限
        User user=new User(userInfo.getUsername(),"{noop}"+userInfo.getPassword(),getAuthority(userInfo.getRoles()));
        return user;
    }


    /**
     * @return 返回一个list集合,集合中装的是用户权限描述
     * @param roles
     */
    public List<SimpleGrantedAuthority> getAuthority(List<Role> roles) {
        List<SimpleGrantedAuthority> list=new ArrayList<>();
        for (Role role : roles) {
            list.add(new SimpleGrantedAuthority(role.getRoleName()));
        }
        return list;
    }
}

(6)IUserDao.java

package lucky.dao;

import lucky.domain.UserInfo;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

public interface IUserDao {
    /**
     * @param username 用户名
     * @Results 映射查询结果集到实体类属性
     * column为数据库字段名,porperty为实体类属性名,jdbcType为数据库字段数据类型,id为是否为主键。
     * 涉及多对多查询,有中间表
     */
    @Select("select * from LUCKY.USERS where username=#{username}")
    @Results({
            @Result(id=true,property = "id",column = "id"),
            @Result(property = "username",column = "username"),
            @Result(property = "email",column = "email"),
            @Result(property = "password",column = "password"),
            @Result(property = "phoneNum",column = "phoneNum"),
            @Result(property = "status",column = "status"),
            @Result(property = "roles",column = "id",javaType = java.util.List.class,many = @Many(select="lucky.dao.IRoleDao.queryByUserId")),
    })
    public UserInfo queryByUsername(String username) throws Exception;
}

(7)用户退出功能

<1>只需要在springsecurity.xml配置文件中添加

<!-- 退出 -->
        <security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.jsp" />

<2>再header.jsp页面中调用即可

              <li class="user-footer">
                            <div class="pull-left">
                                <a href="#" class="btn btn-default btn-flat">修改密码</a>
                            </div>
                            <div class="pull-right">
                                <a href="${pageContext.request.contextPath}/logout"
                                    class="btn btn-default btn-flat">注销</a>
                            </div>
                        </li>

(8)效果图

原文地址:https://www.cnblogs.com/luckyplj/p/11400665.html