Spring Security 配置文件属性说明及注解控制

maven坐标:

            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-web</artifactId>
                <version>5.0.5.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-config</artifactId>
                <version>5.0.5.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-taglibs</artifactId>
                <version>5.0.5.RELEASE</version>
            </dependency>

web委派:

 <!--springsecurity web配置-->
    <filter>
        <!--
          DelegatingFilterProxy用于整合第三方框架
          整合Spring Security时过滤器的名称必须为springSecurityFilterChain,
          否则会抛出NoSuchBeanDefinitionException异常
        -->
        <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>

配置文件:

<?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:context="http://www.springframework.org/schema/context"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:security="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
						http://www.springframework.org/schema/beans/spring-beans.xsd
						http://www.springframework.org/schema/mvc
						http://www.springframework.org/schema/mvc/spring-mvc.xsd
						http://code.alibabatech.com/schema/dubbo
						http://code.alibabatech.com/schema/dubbo/dubbo.xsd
						http://www.springframework.org/schema/context
						http://www.springframework.org/schema/context/spring-context.xsd
                        http://www.springframework.org/schema/security
                        http://www.springframework.org/schema/security/spring-security.xsd">


    <!--配置不进行权限校验的目录-->
    <!--<security:http security="none" pattern="/pages/**"/>-->
    <!--配置可以访问登录界面-->
    <security:http security="none" pattern="/login.html"/>


    <!--
    http:用于定义相关的权限控制
    auto-config: 是否开启自动配置,例如填写true会自动给配置一个登陆界面
        设置为true时框架会提供默认的一些配置,例如提供默认的登录页面、登出处理等
         设置为false时需要显示提供登录表单配置,否则会报错
    user-expressions:是否使用表达式,用于指定intercept-url中的access属性是否使用表达式
    -->
    <security:http auto-config="true" use-expressions="true">
          <!--设置在页面可以通过iframe访问受保护的页面,默认为不允许访问,固定写法-->
        <security:headers>
            <security:frame-options policy="SAMEORIGIN"></security:frame-options>
        </security:headers>


        <!--
        intercept-url:定义一个拦截规则
        pattern:对哪些的URL进行拦截 /** 代表拦截所有目录下的所有URL
        access:在请求对应的URL时需要什么权限,默认配置时它应该是一个以逗号分隔的劫色列表,
                请求的用户只需拥有其中的一个角色就能成功访问对应的URL
                其中ROLE_ADMIN是一个字符串 不代表任何含义
                 如果上方的user-expressions配置为false 则不需要写hasRole,直接写ROLE_ADMIN就可以
                 <security:intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')"/>
        -->
        <!--只要认证通过就可以访问-->
        <security:intercept-url pattern="/pages/a.html" access="isAuthenticated()"/>
        <!--拥有permission权限就可以访问-->
        <security:intercept-url pattern="/pages/b.html" access="hasAnyAuthority('permission_A')"/>
        <security:intercept-url pattern="/pages/d.html" access="hasAnyAuthority('permission_B')"/>
        <!--拥有ROLE_ROOT角色就可以访问-->
        <security:intercept-url pattern="/pages/c.html" access="hasRole('ROLE_ROOT')"/>
        <!--拥有ROLE_ADMIN角色就可以访问d.html页面,
	    注意:此处虽然写的是ADMIN角色,框架会自动加上前缀ROLE_-->
        <security:intercept-url pattern="/index.html"  access="hasRole('ADMIN')" />



        <!--如果我们要使用自己指定的页面作为登录页面,必须配置登陆表单,-->
        <!--
        login-page:指定登陆页面访问URL
        username-parameter:登陆时提交的用户名的参数名称
        password-parameter:登陆时提交的密码的参数名称
        login-processing-url:登录页面表单提交的action地址路径(后台处理,登陆请求的路径,由框架自己提供)
        default-target-url:登陆成功后跳转的页面
        authentication-failure-forward-url:登陆失败跳转的页面
        -->
        <security:form-login login-page="/login.html"
                             username-parameter="username"
                             password-parameter="password"
                             login-processing-url="/login.do"
                             default-target-url="/index.html"
                             authentication-failure-forward-url="/login.html"
                               />
        <!--
                       csrf:对应CsrfFilter过滤器
                       disabled:是否启用CsrfFilter过滤器,如果使用自定义登录页面需要关闭此项,否则登录操作会被禁用(403) true则代表关闭
                   -->
        <security:csrf disabled="true"></security:csrf>

        <!--
          logout:退出登录
          logout-url:退出登录操作对应的请求路径
          logout-success-url:退出登录后的跳转页面
        -->
        <security:logout logout-url="/logout.do"
                         logout-success-url="/login.html" invalidate-session="true"/>
     <!---->
        <!-- Session管理 -->
        <!-- invalid-session-url Session失效后跳转的界面,该页面不受security的控制
                                 在error-if-maximum-exceeded设置true,且超出登陆次数的时候,则会跳转到此页面
            session-fixation-protection是session攻击保护的策略
            migrateSession:这是默认值。其表示在用户登录后将新建一个session,同时将原session中的attribute都copy到新的session中。
            none:表示继续使用原来的session。
            newSession:表示重新创建一个新的session,但是不copy原session拥有的attribute。
         -->
        <security:session-management invalid-session-url="/index.jsp"
                                session-fixation-protection="migrateSession">
            <!--
                当同一用户同时存在的已经通过认证的session数量超过了max-sessions所指定的值时,Spring Security的默认策略是将先前的设为无效。
                如果要限制用户再次登录可以设置concurrency-control的error-if-maximum-exceeded的值为true。
            -->
            <security:concurrency-control error-if-maximum-exceeded="false" max-sessions="1"
                                     expired-url="/login.html" />
        </security:session-management>
    </security:http>



    <!--
        authentication-manager:认证管理器,用于处理认证操作
    -->
    <security:authentication-manager>
        <!--
        authentication-provider:认证提供者,执行具体的认证逻辑
        -->
        <security:authentication-provider user-service-ref="userPassword">
            <!--
            user-service:用于获取用户信息,
                         提供给authentication-provider进行认证
            <security:user-service>
                user:定义用户信息,
                        可以指定用户名 密码 角色 ,后期可以改为从数据库查询的用户信息
                        authorities:表示当前的用户名为admin 密码为 admin
                                    然后内容填写给这个用户分配的一个角色
                         {noop}:表示当前使用的密码为明文

                <security:user name="admin" password="{noop}admin" authorities="ROLE_ADMIN"/>
            </security:user-service>-->
            <security:password-encoder ref="bCryptPasswordEncoder"/>
        </security:authentication-provider>

    </security:authentication-manager>

    <bean id="userPassword" class="com.items.serviceimpl.UserPassword2"/>

    <!--配置密码加密对象-->
    <bean id="bCryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

    <!--开启spring注解-->
    <context:annotation-config></context:annotation-config>


</beans>

配置后,实现UserDetailsService接口,进行登陆配置:

public class UserPassword2 implements UserDetailsService {

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    private Map<String,User> map = new HashMap();

    private void init(){
        User user1 = new User();
        user1.setUsername("admin");
        user1.setPassword(bCryptPasswordEncoder.encode("admin"));

        User user2 = new User();
        user2.setUsername("root");
        user2.setPassword(bCryptPasswordEncoder.encode("1234"));

        map.put(user1.getUsername(),user1);
        map.put(user2.getUsername(),user2);
    }

    //上方为模仿数据库,真实开发不需要配置上方的代码


    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        init();
        System.out.println(username);
        //根据username获取数据库中的用户
        User user = map.get(username);
        if(user == null){
            //用户名不存在的时候
            return null;
        }
        String password =user.getPassword();//noop代表明文
        System.out.println(password);
        //将用户的信息返回给框架
        //框架会进行密码比对(页面提交的密码和数据库的密码)
        List<GrantedAuthority> list = new ArrayList<>();
        //为当前用户授权
        if(username.equals("admin")){
            list.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
            list.add(new SimpleGrantedAuthority("permission_A"));
        }
        if(username.equals("root")){
            list.add(new SimpleGrantedAuthority("permission_B"));
            list.add(new SimpleGrantedAuthority("ROLE_ROOT"));
        }

        /*springsecurity提供的user*/
        org.springframework.security.core.userdetails.User security =
                new org.springframework.security.core.userdetails.User(username, password, list);


        return security;
    }
}

注解:(可以控制类中方法的权限)

使用注解的时候首先开启注解

然后开启springsecurity的注解支持
 

<!--开启包扫描和mvc注解,与上方的spring注解开启一个就可以-->
    <mvc:annotation-driven></mvc:annotation-driven>
    <context:component-scan base-package="com.items.controller"></context:component-scan>

    <!--开启注解方式权限控制-->
    <security:global-method-security pre-post-annotations="enabled" />

然后在类中添加注解:

@PreAuthorize("hasAuthority('add')")//表示用户必须拥有add权限才能调用当前方法

前端VUE权限不足给予提示方法:(固定写法)

              //权限不足提示          
                showMessage(r){
                    if(r == 'Error: Request failed with status code 403'){
                        //权限不足
                        this.$message.error('无访问权限');
                        return;
                    }else{
                        this.$message.error('未知错误');
                        return;
                    }
                },

使用户名动态显示:

在前端页面发送Ajax请求,然后再服务端获取username

@RestController
@RequestMapping("/user")
public class UserController {


    @RequestMapping("/getUsername")
    public Result getUsername(){
        //获取security中的User
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        //获取user中的username
        String username = user.getUsername();
        if(username != null){
            return new Result(true,"获取用户名成功",username);
        }
        return new Result(false,"获取用户名失败");
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值