天天看点

springSecurity 角色权限控制操作后端代码spring-security.xml配置文件Controller层前端页面注意:以下操作的必须是在jsp文件中。在前端页面顶部添加如下:获取当前用户设置访问权限<security:authorize>标签的使用方法使用jstl表达式

后端代码

spring-security.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:security="http://www.springframework.org/schema/security"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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 http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--基于注解的权限控制-->



    <!--开启注解方式权限控制-->
    <!--
        在Controller层方法上使用
        @PreAuthorize("hasAuthority('add')")//表示用户必须拥有add权限才能调用当前方法
        @PreAuthorize("hasRole('ROLE_ADMIN')")//表示用户必须拥有ROLE_ADMIN角色才能调用当前方法
     -->
    <security:global-method-security pre-post-annotations="enabled" />

    <!--
    【重要】【重要】【重要】
    这里面的所有路径必须以/开头,否则启动报错
    -->

    <!--
        http:用于定义相关权限控制
        指定哪些资源不需要进行权限校验,可以使用通配符
        静态资源过滤
    -->
    <security:http security="none" pattern="/js/**" />
    <security:http security="none" pattern="/css/**" />
    <!--  静态资源过滤 匿名访问security="none"  -->
    <security:http pattern="/login.html" security="none"/>
    <security:http pattern="/fail.html" security="none"/>

    <!--  拦截规则配置  -->
    <!--  auto-config: 自动配置,自动生成login页面,login处理,退出处理
            use-expressions: 是否使用spel表达式 true: access的值可以填表达式(hasRole, hasAuthority, hasAny....)
                             false: ROEL_角色名(必须是ROLE_打,否则启动报错), 或 security写死的几个常量
                             开启对表达式的支持
     -->

    <security:http auto-config="true" use-expressions="true">

        <!--  pattern="/**" 拦截所有的路径  access="ROLE_ADMIN"
              要访问符合pattern的url时,登陆用户必须有ROLE_ADMIN的角色,如果没有则不能访问
            security:intercept-url: 拦截的url,pattern 拦截的url对应的格式,格式满足就拦截,可以配置多个
            access:需要什么权限或角色才可以访问符合pattern的url
            pattern="/**" access="ROLE_ADMIN": 只有ROLE_ADMIN角色的人才可以访问我的系统
        -->
        <!--只要认证通过就可以访问-->
        <security:intercept-url pattern="/**"  access="isAuthenticated()" />

        <!--
            login-page:指定登陆页面login.html
            login-processing-url: 告诉security哪个url请求才是做登陆认证,如果将来你的请求符合这个url,security就会帮我们去校验用户与密码,controller中的访问路径
            username-parameter: 登陆时前端传过来的用户名的参数名, request.getParameter("参数名 abc"),前端的name属性值
            password-parameter: 登陆时前端传过来的密码的参数名, request.getParameter("参数名 bbb"),前端的name属性值
            authentication-failure-url: 登陆失败时跳转的路径
            default-target-url: 默认登陆成功后跳转的路径
            always-use-default-target: true:登陆成功后强制跳转到default-target-url里
                                       false:登陆成功后跳转到未登录前访问的页面
        -->
        <security:form-login
                login-page="/login.html"
                login-processing-url="/login"
                username-parameter="abc"
                password-parameter="bbb"
                authentication-failure-url="/fail.html"
                default-target-url="/index.html"
                always-use-default-target="true"
        />

        <!--关闭跨域访问控制-->
        <security:csrf disabled="true"/>

        <!--
            logout:退出登录
            logout-url:退出登录操作对应的请求路径
            logout-success-url:退出登录后的跳转页面
        -->
        <security:logout logout-url="/logout"
                         logout-success-url="/login.html" invalidate-session="true"/>

    </security:http>

    <!--  认证管理器  -->
    <security:authentication-manager>
        <!--添加类实现UserDetailService接口,实现loadByUsername方法,且要返回UserDetails对象(用户名,数据库中的密码,用户所拥有的权限集合)-->
        <!--  认证信息提供者,认证信息的来源
              提供登陆用户信息  用户名、密码、权限集合
              users-service-ref 指向spring容器中一个bean对象, 实现这个UserDetailsService的对象, 提供用户的名称、密码、权限集合
              一旦配置了user-service-ref,就不要配置security:users-service
        -->
        <security:authentication-provider user-service-ref="userService">
            <security:password-encoder ref="encoder"/>
            <!--   登陆用户信息由我们自己来提供         -->
            <!--<security:users-service>
                &lt;!&ndash;   security:users 硬编码一个用户对象在内存中,就不需要去查询数据库了
                       将来应该使用从数据库查询
                       name: 登陆的用户名  password:登陆的密码
                       authorities: 指定的权限(既可以是角色名也可以权限名) authorities与上面access一致才能访问

                       {noop}使用的是明文,no operation 不要对密码做处理
                 &ndash;&gt;
                <security:users name="admin" password="{noop}admin" authorities="ROLE_ADMIN"/>
            </security:users-service>-->
        </security:authentication-provider>
    </security:authentication-manager>

    <bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

    <!--登陆用户信息的提供者-->
    <bean id="userService" class="com.heima.service.UserService"/>

</beans>
           

Controller层

@Controller
@RequestMapping
public class UserController {

    @RequestMapping("/add")
    @PreAuthorize("hasAuthority('add')")//表示用户必须拥有add权限才能调用当前方法
    public String add(){
        System.out.println("add...");
        return "/success";
    }

    @RequestMapping("/update")
    @PreAuthorize("hasRole('ROLE_ADMIN')")//表示用户必须拥有ROLE_ADMIN角色才能调用当前方法
    public String update(){
        System.out.println("update...");
        return "/success";
    }

    @RequestMapping("/delete")
    @PreAuthorize("hasRole('ABC')")//表示用户必须拥有ABC角色才能调用当前方法
    public String delete(){
        System.out.println("delete...");
        return "/success";
    }

}
           

前端页面

注意:以下操作的必须是在jsp文件中。

在前端页面顶部添加如下:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="security"  uri="http://www.springframework.org/security/tags"%>
           

获取当前用户

当前用户:<FONT color="red"> <security:authentication property="principal.username"/> </FONT>
           

设置访问权限

只有ROLE_ADMIN角色才能访问
<security:authorize access="hasRole('ROLE_ADMIN')">
		<TD class=menuSmall>-用户管理</TD>
</security:authorize>
           

<security:authorize>标签的使用方法

<security:authorize>是一个流程控制标签,能够在满足特定安全需求的条件下显示它的内容体。它有三个互斥的参数: 
ifAllGranted——是一个由逗号分隔的权限列表,用户必须拥有所有列出的权限时显示; 
ifAnyGranted——是一个由逗号分隔的权限列表,用户必须至少拥有其中的一个权限时才能显示; 
ifNotGranted——是一个由逗号分隔的权限列表,用户未拥有所有列出的权限时才能显示。 
 
<security:authentication>获得属性的值
比如要获得用户名可以这么写: 
<security:authentication property="principal.username"></security:authentication> 
他有三个属性,property是必须的,另外scope和var,var定义一个变量,scope定义var存在的范围
例子:
有时需要在页面显示用户名,或者根据用户角色显示或者不显示一些内容。这需要使用到spring security提供的标签库。
在页面中引入标签库:
           

使用jstl表达式

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>