SpringSecurity 在SSM框架中的配置

web.xml

<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>

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>

spring-security.xml 配置文件
因为将配置文件分开了,所以这部分是只关于security的

<?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/a.html"></security:http>
    <security:http security="none" pattern="/pages/b.html"></security:http>-->
    <!--<security:http security="none" pattern="/pages/**"></security:http>-->
    <security:http security="none" pattern="/login.html"></security:http>
    <security:http security="none" pattern="/css/**"></security:http>
    <security:http security="none" pattern="/img/**"></security:http>
    <security:http security="none" pattern="/js/**"></security:http>
    <security:http security="none" pattern="/plugins/**"></security:http>
    <!--
        auto-config:自动配置,如果设置为true,表示自动应用一些默认配置,比如框架会提供一个默认的登录页面
        use-expressions:是否使用spring security提供的表达式来描述权限
    -->
    <security:http auto-config="true" use-expressions="true">
        <security:headers>
            <!--设置在页面可以通过iframe访问受保护的页面,默认为不允许访问-->
            <security:frame-options policy="SAMEORIGIN"></security:frame-options>
        </security:headers>
        <!--配置拦截规则,表示拦截所有指定请求   底层通过拦截器实现 -->
        <!--
            pattern:描述拦截规则,要拦截的访问路径
            asscess:指定所需的访问角色或者访问权限    需要上面use-expressions: true
                hasRole("ROLE_ADMIN") 必须ROLE_ADMIN角色
                hasAuthority("add") 必须要有指定权限
                isAuthenticated() 只要认证通过(登录成功)就可以访问
                这目前只是页面的控制   也可以使用注解完成方法的控制 例如控制controller 控制更加精细  1、开启注解扫描,并指定扫描路径   2、开启注解方式控制权限
        -->
        <!--只要认证通过就可以访问-->
        <security:intercept-url pattern="/pages/**" access="isAuthenticated()"/>
<!--        <security:intercept-url pattern="/pages/**" access="hasRole('ADMIN')"/> 你写ADMIN 系统会自动加上ROLE_ 前缀-->

        <!--如果我们要使用自己指定的页面作为登录页面,必须配置登录表单.页面提交的登录表单请求是由框架负责处理-->
        <!-- login-page:指定登录页面访问URL
             username-parameter 指定用户名 -> input的name属性一直
             login-processing-url="/login.do"  框架会给我们处理登录请求 我们甚至不需要写controller
             default-target-url="/pages/main.html"  指定登录成功之后的跳转页面
             authentication-failure-url="/login.html"  登录失败之后的跳转界面
        -->
        <security:form-login
                login-page="/login.html"
                username-parameter="username"
                password-parameter="password"
                login-processing-url="/login.do"
                default-target-url="/pages/main.html"
                authentication-failure-url="/login.html"></security:form-login>

        <!--
          csrf:对应CsrfFilter过滤器
          disabled:是否启用CsrfFilter过滤器,如果使用自定义登录页面需要关闭此项,否则登录操作会被禁用(403)
          框架提供的登录页面 有一个隐藏的<input name="csrf" > 有默认值,经过这个过滤器,检查字符串和内存的(初始化时就会生成,同时赋值给页面)是否一致,一致则框架认为安全
        -->
        <security:csrf disabled="true"></security:csrf>

        <!-- 框架会帮我提供登出功能  前端只需要请求这个路径即可  底层基于过滤器实现
          logout:退出登录
          logout-url:退出登录操作对应的请求路径
          logout-success-url:退出登录后的跳转页面
          invalidate-session="true"  清空session 底层也依赖session
        -->
        <security:logout logout-url="/logout.do"
                         logout-success-url="/login.html" invalidate-session="true"/>

    </security:http>

    <!--配置认证管理器-->
    <security:authentication-manager>
        <!--配置认证提供者   user-service-ref="dataSourceSec" 配置指定处理类 就是下面那个 dataSourceSec  不过我换了一个名字  -->
        <security:authentication-provider user-service-ref="dataSourceSec">
            <!-- 配置一个具体的用户,后期需要从数据库查询用户 password="{noop}1234" {noop}标识为明文   authorities="ROLE_ADMIN" 认证通过就授予角色
                需要从数据库动态查询用户信息 就必须按照框架要求,提供一个实现UserDetailService接口的实现类,并按照要求进行配置即可
            <security:user-service>
                <security:user name="admin" password="{noop}1234" authorities="ROLE_ADMIN"/>
            </security:user-service>
            -->
            <!--指定度密码进行加密的对象 02-->
            <security:password-encoder ref="passwordEncoder"></security:password-encoder>
        </security:authentication-provider>
    </security:authentication-manager>
    <!--已用注解注入 不需bean标签注入    这是实现框架接口的实现类  比如login.do 就会被这个实现类进行处理 -->
    <!-- <bean id="springSecurityUserService" class="com.shk.service.SpringSecurityUserService"/>-->
    <bean id="dataSourceSec" class="com.shk.service.SpringSecurityUserService" />
    <!--指定 配置密码加密对象 01 -->
    <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

    <!-- 1、开启注解扫描,并指定扫描路径 因为在其他配置文件已经开启过了 所以这点不用开启了-->
<!--    <mvc:annotation-driven ></mvc:annotation-driven>-->
    <!-- 2、开启注解方式控制权限 开启注解方式权限控制  在方法上加 @PreAuthorize("hasRole('ADMIN')") 权限和角色的指定参考上面-->
    <security:global-method-security pre-post-annotations="enabled"/>

</beans>

指定接口实现类

public class SpringSecurityUserService implements UserDetailsService {
    /*
     @Autowired  spring security 框架使用的密码加密  框架会将前端传来的密码自动加密然后再和数据库密码进行比对
     private BCryptPasswordEncoder bCryptPasswordEncoder;*/

	// 我使用的是Dubbo远程调用服务,记得修改Dubbo的扫面路径,不然spring不认识 Reference注解
    @Reference  
    private UserService userService;

    /*通过用户名来查询用户 并且授予角色 和权限*/
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println(userService);
        System.out.println(username);
        // bCryptPasswordEncoder.encode("")
        // 根据用户名查询用户信息
        User user = userService.findByUsername(username);
        if (user == null) {
            return null;
        }
        // 框架指定集合 用于存储角色权限
        List<GrantedAuthority> list = new ArrayList<>();
        /*拿到对应的角色*/
        Set<Role> roles = user.getRoles();
        for (Role role : roles) {
            /*获得角色   new SimpleGrantedAuthority() 包装角色和权限数据  ROLE_ 开头系统认为是角色  反之为权限 */
            list.add(new SimpleGrantedAuthority(role.getKeyword()));
            /*通过角色获取到对应权限*/
            Set<Permission> permissions = role.getPermissions();
            for (Permission permission : permissions) {
                list.add(new SimpleGrantedAuthority(permission.getKeyword()));
            }
        }
        // UserDetails 有一个User实现类,框架会帮我们自动核对用户名密码是否正确  默认会将密码处理  如果是明文 需要在密码前拼接 {noop}
        UserDetails userDetails = new org.springframework.security.core.userdetails.User(username, user.getPassword(), list);
        System.out.println(username + ":" + user.getPassword());
        return userDetails;
    }
}

Controller 实现权限管控, 我们只需要在controller类上或者方法上 添加对应注解即可实现权限管控
该用户必须具有此权限才能访问,

@PreAuthorize("hasAuthority('CHECKITEM_DELETE')")  //权限校验
@RequestMapping("/delete")
public Result delete(Integer id){
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值