SpringSecurity 在spring框架下以及springboot下的使用

一、什么是springsecurity?

spring security 是用于spring里提供的一个安全框架,提供认证和授权功能,简单的说,就是作一个权限控制。作为一个入门新手,简单总结一下自己在spring security中的学习。

二、spring框架下springsecurity的用法

常规而言,ssm搭配是Shiro,但是由于此次项目学习的是ssm框架中使用spring security.

1、导入依赖

 <properties>
    <spring.security.version>5.0.1.RELEASE</spring.security.version>
</properties>
<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>

2、在web.xml中创建filter

<!-- 配置类加载类路径的配置文件-->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:conf/spring-security.xml</param-value>
</context-param>
<!-- 配置监听器 -->
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--配置filter-->
<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>

注意: filter-name标签元素中名字“springSecurityFilterChain”不能写错,也不能修改,这个是固定的。

3、spring security 核心文件配置(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"/>

        <!-- 定义跳转的具体的页面 -->
        <security:form-login
                login-page="/login.jsp"
                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.do" 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"/>
</beans>

这个是结合数据库中使用spring security,这里面要注意加密方式。BCrptPasswordEncoder是spring security里的一种比较好的加密方式,可以非常方便的实现密码的加密加盐,相同明文加密出来的结果总是不同,这样就不需要用户去额外保存盐的字段了,这一点比 Shiro 要方便很多。

通过以上步骤,我们已经基本配置好了spring security。
那么在项目中是如何应用的呢?
我们首相分析一下文中的配置,在调用登入页面login.jsp,这个页面在配置不拦截资源里,所以在调用时不会被拦截,肯定是要能够正常访问到。还有就是失败页面,也不会设置成被拦截。
用户登入

4、后端代码层分析

①用户输入账号密码、点击登入

此时,<security:authentication-provider user-service-ref=“userService”>里的userService会去寻找到后台中对应的userService对象,如下代码所示。因为其父类接口IUserService集成了UserDetailsService,所以重写了loadUserByUsername方法。找到userService后调用其loadUserByUsername方法进行账号密码验证。此外还有就是权限的验证。

@Service("userService")
@Transactional
public class UserServiceImpl implements IUserService {
    @Autowired
    private IUserDao userDao;
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserInfo userInfo = null;
        try {
            userInfo = userDao.findByUsername(username);
        }catch (Exception e){
            e.printStackTrace();
        }
        //System.out.println("<<<<<"+userInfo.toString());
        //处理自己的用户对象封装成UserDetails
        User user = new User(userInfo.getUsername(),userInfo.getPassword(),userInfo.getStatus()==0?false:true,true,true,true,getAuthorities(userInfo.getRoles()));
        //System.out.println(">>>>"+user.toString()+user.getPassword());
        return user;
    }
    //对认证主题的应用层面的授权,含当前用户的权限信息
	private List<SimpleGrantedAuthority> getAuthorities(List<Role> roles){
    	List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
        for(Role role : roles) {
            authorities.add(new SimpleGrantedAuthority("ROLE_"+role.getRoleName()));
        }
        return authorities;
	}
}

②用户登入失败和成功跳转

当用户登入失败,即账号密码错误或者权限不足时,会跳转到我们设置好的authentication-failure-url="/failer.jsp"中的failer.jsp页面。成功则是进入我们设置好的main.jsp主页面。

③新建用户后端的密码设置问题

由于我们使用的是BCryptPasswordEncoder加密方式进行验证,那么,在我们新建用户时,保存用户密码也须先对用户密码进行密码编码。在此贴一下新建用户密码的service层代码:

@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
public int save(UserInfo userInfo) throws Exception {
   //创建一个UUID
    userInfo.setId(CreateUUIDUtils.createID());
    //给密码加密
    userInfo.setPassword(bCryptPasswordEncoder.encode(userInfo.getPassword()));
    return userDao.save(userInfo);
}

这里的UUID是由于使用的是mysql数据库,自增主键ID没有想oracle里可以自动设置为UUID格式。
上面可以看到,给密码加密使用是BCryptPasswordEncoder中的encode方法。保证用户登入时传入的密码和数据库中获取的密码是一致的。

猜你喜欢

转载自blog.csdn.net/weixin_39085109/article/details/105184677