Spring Securit学习笔记之SS环境入门开发
文章目录
- Spring Securit学习笔记之SS环境入门开发
- 1. Spring+SpringMVC+Spring Security环境整合
- 1. 创建Maven项目,配置pom.xml文件
- 2. 创建Spring核心配置文件spring-core.xml
- 3. 创建SpringMVC配置文件spring-mvc.xml
- 4. 创建Spring Security配置文件spring-security.xml
- 5. 配置文件web.xml
- 6. 创建页面
- 7. 开发controller
- 2. 自定义登录页面
- 3. 通过 < security:user-service > 配置实现用户权限访问控制
- 4. 自定义 UserDetailService接口实现类实现用户权限访问控制
- 5. 自定义登录成功与失败处理逻辑
- 6. Spring Security认证登录源码流程
Spring Securit学习笔记之SS环境入门开发
1. Spring+SpringMVC+Spring Security环境整合
1. 创建Maven项目,配置pom.xml文件
<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>4.3.10.RELEASE</spring.version>
<spring.security.version>4.2.3.RELEASE</spring.security.version>
<jstl.version>1.2</jstl.version>
<servlet.version>2.5</servlet.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- Spring 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>
<!-- Spring Security dependencies -->
<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>
<!-- jstl for jsp page dependencies -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<!-- servlet-api dependencies -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
2. 创建Spring核心配置文件spring-core.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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
3. 创建SpringMVC配置文件spring-mvc.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: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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 开启控制器注解扫描 -->
<context:component-scan base-package="com.example.controller"></context:component-scan>
<!-- 开启springmvc注解扫描驱动 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 过滤静态资源,静态资源不做处理 -->
<!--<mvc:default-servlet-handler></mvc:default-servlet-handler>-->
<!-- 配置试图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置前缀 -->
<property name="prefix" value="/jsp/"></property>
<!-- 配置后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
4. 创建Spring Security配置文件spring-security.xml
1. 通过< security:http-basic /> 方式的权限登录认证
配置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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.2.xsd">
<!-- <security:http>: spring 过滤器链配置:
1)需要拦截什么资源
2)什么资源什么角色权限
3)定义认证方式:HttpBasic,FormLogin(*)
4)定义登录页面,定义登录请求地址,定义错误处理方式
-->
<security:http>
<!--
pattern: 需要拦截资源
access: 拦截方式
isFullyAuthenticated(): 该资源需要认证才可以访问
isAnonymous():只有匿名用户才可以访问(如果登录用户就无法访问)
permitAll():允许所有人(匿名和登录用户)访问
-->
<security:intercept-url pattern="/product/index" access="permitAll()"/>
<security:intercept-url pattern="/**" access="isFullyAuthenticated()"/>
<!-- security:http-basic: 使用 HttpBasic 方式进行登录(认证) -->
<security:http-basic/>
</security:http>
<!--
security:authentication-manager: 认证管理器
1)认证信息提供方式(账户名,密码,当前用户权限)
-->
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="user" password="user" authorities="ROLE_USER"/>
<security:user name="user" password="user" authorities="ROLE_USER,ROLE_USER"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
2. 通过< security:form-login /> 方式的权限登录认证
配置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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.2.xsd">
<!-- <security:http>: spring 过滤器链配置:
1)需要拦截什么资源
2)什么资源什么角色权限
3)定义认证方式:HttpBasic,FormLogin(*)
4)定义登录页面,定义登录请求地址,定义错误处理方式
-->
<security:http>
<!--
pattern: 需要拦截资源
access: 拦截方式
isFullyAuthenticated(): 该资源需要认证才可以访问
isAnonymous():只有匿名用户才可以访问(如果登录用户就无法访问)
permitAll():允许所有人(匿名和登录用户)访问
-->
<security:intercept-url pattern="/product/index" access="permitAll()"/>
<security:intercept-url pattern="/**" access="isFullyAuthenticated()"/>
<!-- security:form-login: 使用 FormLogin 方式进行登录(认证) -->
<security:form-login/>
<!--security:form-login有以下属性,可根据需求使用
login-page: 自定义登录页面,默认为/login
login-processing-url:登录请求拦截的url,也就是form表单提交时指定的action
default-target-url 默认登录成功后跳转的url
always-use-default-target 是否总是使用默认的登录成功后跳转url
authentication-failure-url 登录失败后跳转的url
username-parameter 用户名的请求字段 默认为userName
password-parameter 密码的请求字段 默认为password
authentication-success-handler-ref 指向一个AuthenticationSuccessHandler用于处理认证成功的请求,不能和default-target-url还有always-use-default-target同时使用
authentication-success-forward-url 用于authentication-failure-handler-ref
authentication-failure-handler-ref 指向一个AuthenticationFailureHandler用于处理失败的认证请求
authentication-failure-forward-url 用于authentication-failure-handler-ref
authentication-details-source-ref 指向一个AuthenticationDetailsSource,在认证过滤器中使用
-->
</security:http>
<!--
security:authentication-manager: 认证管理器
1)认证信息提供方式(账户名,密码,当前用户权限)
-->
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="user" password="user" authorities="ROLE_USER"/>
<security:user name="user" password="user" authorities="ROLE_USER,ROLE_USER"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
5. 配置文件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">
<!-- SpringSecurity 过滤器链 -->
<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>
<!-- 启动 Spring 配置spring工厂监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 全局加载配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/spring-core.xml
classpath:/spring-security.xml
</param-value>
</context-param>
<!-- 启动 SpringMVC 配置核心入口servlet -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定servlet去哪加载springmvc的配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring-mvc.xml</param-value>
</init-param>
<!-- 服务器启动加载 Servlet 优先级 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
6. 创建页面
- index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <a href="/product/add">add</a> <a href="/product/delete">delete</a> <a href="/product/list">list</a> <a href="/product/update">update</a> </body> </html>
- productAdd.jsp、productDelete.jsp、productList.jsp、productUpdate.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>欢迎</h1> <a href="/product/index">index</a> </body> </html>
7. 开发controller
package com.example.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/product")
public class ProductController {
/**
* 商品添加
*/
@RequestMapping("/index")
public String index(){
return "index";
}
/**
* 商品添加
*/
@RequestMapping("/add")
public String add(){
return "product/productAdd";
}
/**
* 商品修改
*/
@RequestMapping("/update")
public String update(){
return "product/productUpdate";
}
/**
* 商品查询
*/
@RequestMapping("/list")
public String list(){
return "product/productList";
}
/**
* 商品删除
*/
@RequestMapping("/delete")
public String delete(){
return "product/productDelete";
}
}
2. 自定义登录页面
1. 开发登录界面
<%@page pageEncoding="UTF-8" %>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>Hello World!</h2>
<h3>表单登录</h3>
<form action="/login" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td colspan="2"><button type="submit">登录</button></td>
</tr>
</table>
</form>
</body>
</html>
2. 配置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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.2.xsd">
<!-- <security:http>: spring 过滤器链配置:
1)需要拦截什么资源
2)什么资源什么角色权限
3)定义认证方式:HttpBasic,FormLogin(*)
4)定义登录页面,定义登录请求地址,定义错误处理方式
-->
<security:http>
<!--
pattern: 需要拦截资源
access: 拦截方式
isFullyAuthenticated(): 该资源需要认证才可以访问
isAnonymous():只有匿名用户才可以访问(如果登录用户就无法访问)
permitAll():允许所有人(匿名和登录用户)访问
-->
<security:intercept-url pattern="/product/index" access="permitAll()"/>
<!-- 自定义登录界面-->
<security:intercept-url pattern="/userLogin.jsp" access="permitAll()"/>
<security:intercept-url pattern="/**" access="isFullyAuthenticated()"/>
<!--
login-page: 自定义登录页面,默认为/login
login-processing-url:登录请求拦截的url,也就是form表单提交时指定的action
default-target-url 默认登录成功后跳转的url
always-use-default-target 是否总是使用默认的登录成功后跳转url
authentication-failure-url 登录失败后跳转的url
username-parameter 用户名的请求字段 默认为userName
password-parameter 密码的请求字段 默认为password
authentication-success-handler-ref 指向一个AuthenticationSuccessHandler用于处理认证成功的请求,不能和default-target-url还有always-use-default-target同时使用
authentication-success-forward-url 用于authentication-failure-handler-ref
authentication-failure-handler-ref 指向一个AuthenticationFailureHandler用于处理失败的认证请求
authentication-failure-forward-url 用于authentication-failure-handler-ref
authentication-details-source-ref 指向一个AuthenticationDetailsSource,在认证过滤器中使用
-->
<security:form-login login-page="/userLogin.jsp"
login-processing-url="/login"
default-target-url="/jsp/index.jsp"
username-parameter="username" <!-- 表示登录时用户名使用的是哪个参数 -->
password-parameter="password" <!-- 表示登录时密码使用的是哪个参数 -->
/>
<!-- 关闭 Spring Security CSRF 机制 -->
<security:csrf disabled="true"/>
</security:http>
<!--
security:authentication-manager: 认证管理器
1)认证信息提供方式(账户名,密码,当前用户权限)
-->
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="user" password="user" authorities="ROLE_USER"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
3. 通过 < security:user-service > 配置实现用户权限访问控制
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.2.xsd">
<!-- <security:http>: spring 过滤器链配置:
1)需要拦截什么资源
2)什么资源什么角色权限
3)定义认证方式:HttpBasic,FormLogin(*)
4)定义登录页面,定义登录请求地址,定义错误处理方式
-->
<security:http>
<!--
pattern: 需要拦截资源
access: 拦截方式
isFullyAuthenticated(): 该资源需要认证才可以访问
isAnonymous():只有匿名用户才可以访问(如果登录用户就无法访问)
permitAll():允许所有人(匿名和登录用户)访问
-->
<security:intercept-url pattern="/product/index" access="permitAll()"/>
<!-- 自定义登录界面-->
<security:intercept-url pattern="/userLogin.jsp" access="permitAll()"/>
<!-- 定义每个资源的访问权限 -->
<security:intercept-url pattern="/product/add" access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/product/update" access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/product/list" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/product/delete" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/**" access="isFullyAuthenticated()"/>
<!-- security:http-basic: 使用 HttpBasic 方式进行登录(认证) -->
<!--<security:http-basic/>-->
<!-- security:form-login: 使用 FormLogin 方式进行登录(认证) -->
<!--<security:form-login/>-->
<!--
login-page: 自定义登录页面,默认为/login
login-processing-url:登录请求拦截的url,也就是form表单提交时指定的action
default-target-url 默认登录成功后跳转的url
always-use-default-target 是否总是使用默认的登录成功后跳转url
authentication-failure-url 登录失败后跳转的url
username-parameter 用户名的请求字段 默认为userName
password-parameter 密码的请求字段 默认为password
authentication-success-handler-ref 指向一个AuthenticationSuccessHandler用于处理认证成功的请求,不能和default-target-url还有always-use-default-target同时使用
authentication-success-forward-url 用于authentication-failure-handler-ref
authentication-failure-handler-ref 指向一个AuthenticationFailureHandler用于处理失败的认证请求
authentication-failure-forward-url 用于authentication-failure-handler-ref
authentication-details-source-ref 指向一个AuthenticationDetailsSource,在认证过滤器中使用
-->
<security:form-login login-page="/userLogin.jsp"
login-processing-url="/login"
default-target-url="/jsp/index.jsp"
username-parameter="username"
password-parameter="password"/>
<!-- 自定义权限不足处理 -->
<security:access-denied-handler error-page="/error.jsp"/>
<!-- 关闭 Spring Security CSRF 机制 -->
<security:csrf disabled="true"/>
</security:http>
<!--
security:authentication-manager: 认证管理器
1)认证信息提供方式(账户名,密码,当前用户权限)
-->
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<!-- 两种认证身份 -->
<security:user name="user" password="user" authorities="ROLE_USER"/>
<security:user name="admin" password="admin" authorities="ROLE_ADMIN"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
4. 自定义 UserDetailService接口实现类实现用户权限访问控制
关键:使用 UserDetailService 接口
1. 开发UserDetailService接口实现类
package com.example.config;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
public class MyUserDetailService implements UserDetailsService {
/**
* loadUserByUsername: 读取用户信息
* @param username
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//UserDetails: 封装用户数据的接口
User user = new User( "user","user", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));
return user;
}
}
其中 User 类就是 UserDetail 实现类,用于封装数据库账户信息
2. 配置spring-security.xml文件
加入如下配置:
......
<!-- 通过user-service-ref="myUserDetailService"的配置,使用UserDetailService接口实现类实现权限控制 -->
<security:authentication-provider user-service-ref="myUserDetailService">
......
<!-- 将自定义的UserDetailService接口实现类MyUserDetailService注入spring容器 -->
<bean id="myUserDetailService" class="com.example.config.MyUserDetailService"/>
......
完整的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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.2.xsd">
<!-- <security:http>: spring 过滤器链配置:
1)需要拦截什么资源
2)什么资源什么角色权限
3)定义认证方式:HttpBasic,FormLogin(*)
4)定义登录页面,定义登录请求地址,定义错误处理方式
-->
<security:http>
<!--
pattern: 需要拦截资源
access: 拦截方式
isFullyAuthenticated(): 该资源需要认证才可以访问
isAnonymous():只有匿名用户才可以访问(如果登录用户就无法访问)
permitAll():允许所有人(匿名和登录用户)访问
-->
<security:intercept-url pattern="/product/index" access="permitAll()"/>
<!-- 自定义登录界面-->
<security:intercept-url pattern="/userLogin.jsp" access="permitAll()"/>
<security:intercept-url pattern="/product/add" access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/product/update" access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/product/list" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/product/delete" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/**" access="isFullyAuthenticated()"/>
<!-- security:http-basic: 使用 HttpBasic 方式进行登录(认证) -->
<!--<security:http-basic/>-->
<!-- security:form-login: 使用 FormLogin 方式进行登录(认证) -->
<!--<security:form-login/>-->
<!--
login-page: 自定义登录页面,默认为/login
login-processing-url:登录请求拦截的url,也就是form表单提交时指定的action
default-target-url 默认登录成功后跳转的url
always-use-default-target 是否总是使用默认的登录成功后跳转url
authentication-failure-url 登录失败后跳转的url
username-parameter 用户名的请求字段 默认为userName
password-parameter 密码的请求字段 默认为password
authentication-success-handler-ref 指向一个AuthenticationSuccessHandler用于处理认证成功的请求,不能和default-target-url还有always-use-default-target同时使用
authentication-success-forward-url 用于authentication-failure-handler-ref
authentication-failure-handler-ref 指向一个AuthenticationFailureHandler用于处理失败的认证请求
authentication-failure-forward-url 用于authentication-failure-handler-ref
authentication-details-source-ref 指向一个AuthenticationDetailsSource,在认证过滤器中使用
-->
<security:form-login login-page="/userLogin.jsp"
login-processing-url="/login"
default-target-url="/jsp/index.jsp"
username-parameter="username"
password-parameter="password"/>
<!-- 自定义权限不足处理 -->
<security:access-denied-handler error-page="/error.jsp"/>
<!-- 关闭 Spring Security CSRF 机制 -->
<security:csrf disabled="true"/>
</security:http>
<!--
security:authentication-manager: 认证管理器
1)认证信息提供方式(账户名,密码,当前用户权限)
-->
<security:authentication-manager>
<!-- 通过user-service-ref="myUserDetailService"的配置,使用UserDetailService接口实现类实现权限控制 -->
<security:authentication-provider user-service-ref="myUserDetailService">
<!--<security:user-service>-->
<!--<security:user name="user" password="user" authorities="ROLE_USER"/>-->
<!--<security:user name="admin" password="admin" authorities="ROLE_ADMIN"/>-->
<!--</security:user-service>-->
</security:authentication-provider>
</security:authentication-manager>
<!-- 将自定义的UserDetailService接口实现类MyUserDetailService注入spring容器 -->
<bean id="myUserDetailService" class="com.example.config.MyUserDetailService"/>
</beans>
5. 自定义登录成功与失败处理逻辑
关键:
1)登录成功处理:AuthenticationSuccessHandler接口
2)登录失败处理:AuthenticationFailureHandler接口
1. 自定义登录成功处理逻辑
1. 引入jackson依赖
修改pom.xml文件
<!-- jackson 依赖 -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
2. 开发AuthenticationSuccessHandler接口实现类
package com.example.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
//ObjectMapper: jackson 框架的工具类,用于转换对象为 json 字符串
private ObjectMapper objectMapper = new ObjectMapper();
/**
* @param request
* @param response
* @param authentication :代表认证成功后的信息
* @throws IOException
* @throws ServletException
*/
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//返回 json 字符串给前端
Map result = new HashMap();
result.put("succcess",true);
String json = objectMapper.writeValueAsString(result);
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(json);
}
}
3. 配置spring-security.xml文件
加入如下配置:
......
<security:form-login
...... 其他属性配置
authentication-success-handler-ref="myAuthenticationSuccessHandler"
/>
......
<!-- 将自定义的AuthenticationSuccessHandler接口实现类MyAuthenticationSuccessHandler注入spring容器 -->
<bean id="myAuthenticationSuccessHandler" class="com.example.config.MyAuthenticationSuccessHandler"/>
......
完整的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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.2.xsd">
<!-- <security:http>: spring 过滤器链配置:
1)需要拦截什么资源
2)什么资源什么角色权限
3)定义认证方式:HttpBasic,FormLogin(*)
4)定义登录页面,定义登录请求地址,定义错误处理方式
-->
<security:http>
<!--
pattern: 需要拦截资源
access: 拦截方式
isFullyAuthenticated(): 该资源需要认证才可以访问
isAnonymous():只有匿名用户才可以访问(如果登录用户就无法访问)
permitAll():允许所有人(匿名和登录用户)访问
-->
<security:intercept-url pattern="/product/index" access="permitAll()"/>
<!-- 自定义登录界面-->
<security:intercept-url pattern="/userLogin.jsp" access="permitAll()"/>
<security:intercept-url pattern="/product/add" access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/product/update" access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/product/list" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/product/delete" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/**" access="isFullyAuthenticated()"/>
<!-- security:http-basic: 使用 HttpBasic 方式进行登录(认证) -->
<!--<security:http-basic/>-->
<!-- security:form-login: 使用 FormLogin 方式进行登录(认证) -->
<!--<security:form-login/>-->
<!--
login-page: 自定义登录页面,默认为/login
login-processing-url:登录请求拦截的url,也就是form表单提交时指定的action
default-target-url 默认登录成功后跳转的url
always-use-default-target 是否总是使用默认的登录成功后跳转url
authentication-failure-url 登录失败后跳转的url
username-parameter 用户名的请求字段 默认为userName
password-parameter 密码的请求字段 默认为password
authentication-success-handler-ref 指向一个AuthenticationSuccessHandler用于处理认证成功的请求,不能和default-target-url还有always-use-default-target同时使用
authentication-success-forward-url 用于authentication-failure-handler-ref
authentication-failure-handler-ref 指向一个AuthenticationFailureHandler用于处理失败的认证请求
authentication-failure-forward-url 用于authentication-failure-handler-ref
authentication-details-source-ref 指向一个AuthenticationDetailsSource,在认证过滤器中使用
-->
<security:form-login login-page="/userLogin.jsp"
login-processing-url="/login"
default-target-url="/jsp/index.jsp"
username-parameter="username"
password-parameter="password"
authentication-success-handler-ref="myAuthenticationSuccessHandler"
/>
<!-- 自定义权限不足处理 -->
<security:access-denied-handler error-page="/error.jsp"/>
<!-- 关闭 Spring Security CSRF 机制 -->
<security:csrf disabled="true"/>
</security:http>
<!--
security:authentication-manager: 认证管理器
1)认证信息提供方式(账户名,密码,当前用户权限)
-->
<security:authentication-manager>
<!-- 通过user-service-ref="myUserDetailService"的配置,使用UserDetailService接口实现类实现权限控制 -->
<security:authentication-provider user-service-ref="myUserDetailService">
<!--<security:user-service>-->
<!--<security:user name="user" password="user" authorities="ROLE_USER"/>-->
<!--<security:user name="admin" password="admin" authorities="ROLE_ADMIN"/>-->
<!--</security:user-service>-->
</security:authentication-provider>
</security:authentication-manager>
<!-- 将自定义的UserDetailService接口实现类MyUserDetailService注入spring容器 -->
<bean id="myUserDetailService" class="com.example.config.MyUserDetailService"/>
<!-- 将自定义的AuthenticationSuccessHandler接口实现类MyAuthenticationSuccessHandler注入spring容器 -->
<bean id="myAuthenticationSuccessHandler" class="com.example.config.MyAuthenticationSuccessHandler"/>
</beans>
2. 自定义登录失败处理逻辑
1. 引入jackson依赖
修改pom.xml文件
<!-- jackson 依赖 -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
2. 开发AuthenticationSuccessHandler接口实现类
package com.example.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
//ObjectMapper: jackson 框架的工具类,用于转换对象为 json 字符串
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
//返回 json 字符串给前端
Map result = new HashMap();
result.put("succcess",false);
String json = objectMapper.writeValueAsString(result);
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(json);
}
}
3. 配置spring-security.xml文件
加入如下配置:
......
<security:form-login
...... 其他属性配置
authentication-failure-handler-ref="myAuthenticationFailureHandler"
/>
......
<!-- 将自定义的AuthenticationFailureHandler接口实现类MyAuthenticationFailureHandler注入spring容器 -->
<bean id="myAuthenticationFailureHandler" class="com.example.config.MyAuthenticationFailureHandler"/>
......
完整的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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.2.xsd">
<!-- <security:http>: spring 过滤器链配置:
1)需要拦截什么资源
2)什么资源什么角色权限
3)定义认证方式:HttpBasic,FormLogin(*)
4)定义登录页面,定义登录请求地址,定义错误处理方式
-->
<security:http>
<!--
pattern: 需要拦截资源
access: 拦截方式
isFullyAuthenticated(): 该资源需要认证才可以访问
isAnonymous():只有匿名用户才可以访问(如果登录用户就无法访问)
permitAll():允许所有人(匿名和登录用户)访问
-->
<security:intercept-url pattern="/product/index" access="permitAll()"/>
<!-- 自定义登录界面-->
<security:intercept-url pattern="/userLogin.jsp" access="permitAll()"/>
<security:intercept-url pattern="/product/add" access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/product/update" access="hasRole('ROLE_USER')"/>
<security:intercept-url pattern="/product/list" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/product/delete" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/**" access="isFullyAuthenticated()"/>
<!-- security:http-basic: 使用 HttpBasic 方式进行登录(认证) -->
<!--<security:http-basic/>-->
<!-- security:form-login: 使用 FormLogin 方式进行登录(认证) -->
<!--<security:form-login/>-->
<!--
login-page: 自定义登录页面,默认为/login
login-processing-url:登录请求拦截的url,也就是form表单提交时指定的action
default-target-url 默认登录成功后跳转的url
always-use-default-target 是否总是使用默认的登录成功后跳转url
authentication-failure-url 登录失败后跳转的url
username-parameter 用户名的请求字段 默认为userName
password-parameter 密码的请求字段 默认为password
authentication-success-handler-ref 指向一个AuthenticationSuccessHandler用于处理认证成功的请求,不能和default-target-url还有always-use-default-target同时使用
authentication-success-forward-url 用于authentication-failure-handler-ref
authentication-failure-handler-ref 指向一个AuthenticationFailureHandler用于处理失败的认证请求
authentication-failure-forward-url 用于authentication-failure-handler-ref
authentication-details-source-ref 指向一个AuthenticationDetailsSource,在认证过滤器中使用
-->
<security:form-login login-page="/userLogin.jsp"
login-processing-url="/login"
default-target-url="/jsp/index.jsp"
username-parameter="username"
password-parameter="password"
authentication-success-handler-ref="myAuthenticationSuccessHandler"
authentication-failure-handler-ref="myAuthenticationFailureHandler"
/>
<!-- 自定义权限不足处理 -->
<security:access-denied-handler error-page="/error.jsp"/>
<!-- 关闭 Spring Security CSRF 机制 -->
<security:csrf disabled="true"/>
</security:http>
<!--
security:authentication-manager: 认证管理器
1)认证信息提供方式(账户名,密码,当前用户权限)
-->
<security:authentication-manager>
<!-- 通过user-service-ref="myUserDetailService"的配置,使用UserDetailService接口实现类实现权限控制 -->
<security:authentication-provider user-service-ref="myUserDetailService">
<!--<security:user-service>-->
<!--<security:user name="user" password="user" authorities="ROLE_USER"/>-->
<!--<security:user name="admin" password="admin" authorities="ROLE_ADMIN"/>-->
<!--</security:user-service>-->
</security:authentication-provider>
</security:authentication-manager>
<!-- 将自定义的UserDetailService接口实现类MyUserDetailService注入spring容器 -->
<bean id="myUserDetailService" class="com.example.config.MyUserDetailService"/>
<!-- 将自定义的AuthenticationSuccessHandler接口实现类MyAuthenticationSuccessHandler注入spring容器 -->
<bean id="myAuthenticationSuccessHandler" class="com.example.config.MyAuthenticationSuccessHandler"/>
<!-- 将自定义的AuthenticationFailureHandler接口实现类MyAuthenticationFailureHandler注入spring容器 -->
<bean id="myAuthenticationFailureHandler" class="com.example.config.MyAuthenticationFailureHandler"/>
</beans>
6. Spring Security认证登录源码流程
参考:https://blog.****.net/abcwanglinyong/article/details/80981389