Securtity-角色权限控制-Spring Security最简单全面教程(带Demo)spring安全组件验证中文乱码问题 Spring security(1)

一、SpringSecurity概述

1.1 Spring介绍

Spring Security是为Spring提供的一套声明式安全框架,它提供了一套完整的安全解决方案,能够在web请求级别和方法调用级别进行身份验证与授权; 因为是基于spring框架,所以它充分利用了AOP|DI技术。

Spring security主要解决两个问题

  • Web请求级别
    • 通过Servlet规范的Filter过滤器,对访问资源进行控制。
  • 方法调用级别
    • 通过AOP切面技术,对于特定的方法进行权限控制与访问授权。
关键词 描述
认证 是为用户建立一个他所声明的主体,主体一般指的是用户、设备或者系统中执行动作的其他系统;
授权 是指用户能否在应用中执行某个操作;

1.2 Maven依赖


 <!--引入security依赖-->
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-web</artifactId>
      <version>5.0.1.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-config</artifactId>
      <version>5.0.1.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-core</artifactId>
      <version>5.0.1.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-taglibs</artifactId>
      <version>5.0.1.RELEASE</version>

二、Spring Security快速入门Demo

2.1 导入依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.atjianyi</groupId>
  <artifactId>spring_secruity_demoTest</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>spring_secruity_demoTest Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
    <spring.version>5.0.2.RELEASE</spring.version>
    <spring.security.version>5.0.1.RELEASE</spring.security.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>

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

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>

  </dependencies>

  <build>
    <finalName>spring_secruity_demoTest</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>

    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
          <port>8080</port>
          <path>/</path>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>


2.2 配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">
  <display-name>SpringSecurity314</display-name>

<!--初始化xml文件-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring-security.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
<!-- 配置过滤器 过滤器名称不能改变 -->
  <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>
  
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

2.3 核心配置文件

form-login中的属性 描述
login-page 自定义登陆页面的位置
login-processing-url 访问的URL
username-parameter 用户名表单参数绑定
password-parameter 密码表单参数绑定
authentication-failure-url 权限校验失败后的登陆地址
authentication-success-forward-url 登陆成功并且权限校验通过
default-target-url 只需要登陆成功,就跳转到URL(权限可能不通过403状态)
<?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 security="none" pattern="/login.html"/>
    <security:http security="none" pattern="/error.html"/>

    <security:http auto-config="true" use-expressions="false">
<!--   配置需要认证的资源连接和角色    -->
        <security:intercept-url pattern="/**"  access="ROLE_USER" />
<!--   自定义登陆页面

     -->
         <security:form-login
                 login-page="/login.html"
                 login-processing-url="/login"
                 username-parameter="username"
                 password-parameter="password"
                 authentication-failure-url="/error.html"
                 default-target-url="/succeed.html"
                 authentication-success-forward-url="/succeed.html"
           />
        <!--  关闭跨域登陆支持  -->
        <security:csrf disabled="true"/>
    </security:http>
<!--  在内存当中配置用户角色  -->
    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <security:user name="user" password="{noop}user"
                               authorities="ROLE_USER" />
                <security:user name="admin" password="{noop}admin"
                               authorities="ROLE_ADMIN" />
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
</beans>

三、Spring Security使用数据库认证

3.1 传统的登陆操作

在这里插入图片描述

3.2 使用SpringSecurity认证操作

在这里插入图片描述

3.2.1 数据库认证

在spring security当中要想想使用数据库认证操作,有很多种操作,这里我们及那个使用userDetails完成

  • UserDetail源码
  • userDetails是一个接口,我们在使用的时候,需要将他实现,现在我们可以理解为,它的作用封装当前用户认证信息的类! 当然,我们也可以使用spring security为我们提供实现user类;
public interface UserDetails extends Serializable {
    
    
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}
  • User类的源码
public class User implements UserDetails, CredentialsContainer {
    
    
private String password;
private final String username;
private final Set<GrantedAuthority> authorities;//角色权限组
private final boolean accountNonExpired; //帐户是否过期
private final boolean accountNonLocked; //帐户是否锁定
private final boolean credentialsNonExpired; //认证是否过期
private final boolean enabled; //帐户是否可用
  • userDetailsService
public interface UserDetailsService {
    
    
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}

在之前Spring security实现用户登陆流程我们讲过,我们的用户业务逻辑层需要实现此接口,并重写对应的方法。

3.2.2 应用实例

  1. 导入对应依赖,详见1.2(在5.2.0以上版本可能于tomcat7不兼容)
  2. 配置过滤器
  • 在于Spring整合时候,只需要同时加载springsecurity的配置文件就可以了。
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/applicationContext.xml classpath:spring/spring-sercurty-confing.xml</param-value>
    </context-param>
  1. 编写配置文件(配置指定Service)
    在这里插入图片描述
<!--省略约束,和不需要拦截的资源->...
    <!--
    	配置具体的规则
    	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"
                login-processing-url="/login.do"
                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>

如果不配置加密方式,那么在转换UserDateails时候,在密码前面加上{noop}

  1. 编写Service继承UserDatealisService
    在这里插入图片描述
//此处UserService就是上面配置文件配置的提供器。
@Service("userService")
@Transactional
public class UserServiceImpl implements UserService {
    
    
    @Autowired
    private UserMapper userMapper;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    
    
        UserInfo userInfo = null;
        try {
    
    
        //根据表单传过来的名称,查询数据空中的用户。
            userInfo = userMapper.findUserByName(username);
            System.out.println(userInfo);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        //将查询的对象放入到UserDatelias的实现
        User user = new User(userInfo.getUserName(),"{noop}"+userInfo.getUserPwd(),getAuthority(userInfo.getRoleList()));
        return user;
    }

    public List<SimpleGrantedAuthority> getAuthority(List<Role> roleList){
    
    
    //将角色组放入到集合当中返回
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        for (Role role : roleList) {
    
    
            authorities.add(new SimpleGrantedAuthority("ROLE_"+role.getRoleName()));
        }
        return authorities;
    }

四、用户密码加密和加密验证登陆

4.1 密码加密

  • BCryptPasswordEncoder
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
//生成加密后字符串
String encode = bCryptPasswordEncoder.encode(password);

4.2 配置解密

  <!-- 切换成数据库中的用户名和密码 -->
    <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"/>


注意事项:

  • tomcat于SpringSecurity
    • 再SpringSecurity5.2.0以上版本可能不支持tomcat7
  • 安全验证时候,表单提交乱码问题

在web.xml配置文件中将springSecurityFilterChain拦截器放在了
characterEncodingFilter前面,导致会先加载springSecurityFilterChain拦截器
再加载characterEncodingFilter拦截器,而加载springSecurityFilterChain拦截器
时会自动加载CsrfFilter拦截器,这个拦截器会给所有的请求增加一个名为CSRF Token的请求头,这个请求头会将编码设定为iso-8859-1且无法修改,故而characterEncodingFilter
就失去了它原本的作用。

猜你喜欢

转载自blog.csdn.net/Janyi_/article/details/114029129
今日推荐