spring Security用户认证框架
spring security 简介
spring security 的核心功能主要包括:
认证 (你是谁)
授权 (你能干什么)
攻击防护 (防止伪造身份)
其核心就是一组过滤器链,项目启动后将会自动配置。最核心的就是 Basic Authentication Filter 用来认证用户的身份,一个在spring security中一种过滤器处理一种认证方式。
比如,对于username password认证过滤器来说,
会检查是否是一个登录请求;
是否包含username 和 password (也就是该过滤器需要的一些认证信息) ;
如果不满足则放行给下一个。
1.创建mavenWeb项目
<?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.sxw</groupId>
<artifactId>spring-security</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<url>http://www.example.com</url>
<properties>
<jdk.version>1.8</jdk.version>
<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>
<!-- 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 -->
<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 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- jdk版本插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
<!-- tomcat7插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8080</port>
<path>/ss1</path>
<server>tomcat7</server>
</configuration>
</plugin>
</plugins>
</build>
</project>2.创建Spring相关配置文件
1)applicationContext.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">
<import resource="classpath:spring-security.xml"/>
</beans>2)springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:contenxt="http://www.springframework.org/schema/context"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描Controller类-->
<contenxt:component-scan base-package="com.sxw"/>
<!--注解方式处理器映射器和处理器适配器 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀 -->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- 后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:contenxt="http://www.springframework.org/schema/context"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描Controller类-->
<contenxt:component-scan base-package="com.sxw"/>
<!--注解方式处理器映射器和处理器适配器 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀 -->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- 后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>3)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" 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/>-->
<!--表单形式的验证
login-page 自定义登录页面
login-processing-url:登录请求的地址
authentication-success-handler-ref:登录成功之后的情况
authentication-failure-handler-ref: 登录失败之后的情况-->
<security:form-login
login-page="/userLogin"
login-processing-url="/securityLogin"
default-target-url="/product/index"
authentication-success-handler-ref="myAuthenticationSuccessHandler"
authentication-failure-handler-ref="myAuthenticationFailureHandler"
/>
<!--关闭spring security CSRF机制-->
<security:csrf disabled="true"/>
<!-- 自定义权限不足处理 -->
<security:access-denied-handler error-page="/error"/>
</security:http>
<security:authentication-manager>
<!-- security:authentication-manager: 认证管理器
1)认证信息提供方式(账户名,密码,当前用户权限)
-->
<!-- <security:authentication-provider>
<security:user-service>
<security:user name="eric" password="123456" authorities="ROLE_USER"/>
<security:user name="jack" password="123456" authorities="ROLE_ADMIN"/>
</security:user-service>
</security:authentication-provider>-->
<!--定义USerDetailServer方式-->
<security:authentication-provider user-service-ref="myUserDemoServer"/>
</security:authentication-manager>
<bean id="myUserDemoServer" class="com.sxw.security.MyUserDemoServer"/>
<bean id="myAuthenticationSuccessHandler" class="com.sxw.security.MyAuthenticationSuccessHandler"/>
<bean id="myAuthenticationFailureHandler" class="com.sxw.security.MyAuthenticationFailureHandler"/>
</beans>3.编写web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 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 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml
</param-value>
</context-param>
<!--启动SpringMVC-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 服务器启动加载Servlet-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>3.编写拦截器
1)登录成功处理
/**
* @description: 登录成功处理
* @author:
* @createDate: 2020/4/4
* @version: 1.0
*/
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
/*json框架的工具类*/
private ObjectMapper objectMapper = new ObjectMapper();
/**
*
* @description:TODO
* @params:3. 认证成功后的信息 * @return:
* @author:
* @time: 2020/4/4 12:26
*/
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//返回json字符串
Map<String,Object> result = new HashMap();
result.put("success",true);
String json =objectMapper.writeValueAsString(result);
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(json);
}
}2)登录失败的逻辑
/**
* @description: 登录失败的逻辑
* @author:
* @createDate: 2020/4/4
* @version: 1.0
*/
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
/*json框架的工具类*/
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
//返回json字符串
Map<String,Object> result = new HashMap();
result.put("Failure",false);
String json =objectMapper.writeValueAsString(result);
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(json);
}
}3)用户权限的管理
/**
* @description: 用户权限的管理
* @author:
* @createDate: 2020/4/4
* @version: 1.0
*/
public class MyUserDemoServer implements UserDetailsService {
/**
*
* @description:读取数据库的信息
* @params:
* @return:
* @author:
* @time: 2020/4/4 12:00
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//UserDetails: 封装用户数据的接口
User user = new User("eric","123456",
AuthorityUtils.
commaSeparatedStringToAuthorityList("ROLE_USER"));
return user;
}
}2.SpringBoot整合
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.sxw</groupId>
<artifactId>springsecurityboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springsecurityboot</name>
<packaging>war</packaging>
<description>Demo project for Spring Boot</description>
<dependencies>
<!-- web支持,SpringMVC, Servlet支持等 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
<!-- jstl for jsp page -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.7</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.41</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>2.2.6.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.5.RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
<!-- 修改thymeleaf的版本 -->
<thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.version>
</properties>
</project>@Component
public class User implements UserDetails{
private Integer id; //int(10) NOT NULL,
private String username; //varchar(50) DEFAULT NULL,
private String realname; //varchar(50) DEFAULT NULL,
private String password; //varchar(50) DEFAULT NULL,
private Date createDate; //date DEFAULT NULL,
private Date lastLoginTime; //date DEFAULT NULL,
private boolean enabled; //int(5) DEFAULT NULL,
private boolean accountNonExpired; //int(5) DEFAULT NULL,
private boolean accountNonLocked; //int(5) DEFAULT NULL,
private boolean credentialsNonExpired; //int(5) DEFAULT NULL,
//用户拥有的所有权限
private List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
public List<GrantedAuthority> getAuthorities() {
return authorities;
}
public void setAuthorities(List<GrantedAuthority> authorities) {
this.authorities = authorities;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getRealname() {
return realname;
}
public void setRealname(String realname) {
this.realname = realname;
}
@Override
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getLastLoginTime() {
return lastLoginTime;
}
public void setLastLoginTime(Date lastLoginTime) {
this.lastLoginTime = lastLoginTime;
}
@Override
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@Override
public boolean isAccountNonExpired() {
return accountNonExpired;
}
public void setAccountNonExpired(boolean accountNonExpired) {
this.accountNonExpired = accountNonExpired;
}
@Override
public boolean isAccountNonLocked() {
return accountNonLocked;
}
public void setAccountNonLocked(boolean accountNonLocked) {
this.accountNonLocked = accountNonLocked;
}
@Override
public boolean isCredentialsNonExpired() {
return credentialsNonExpired;
}
public void setCredentialsNonExpired(boolean credentialsNonExpired) {
this.credentialsNonExpired = credentialsNonExpired;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username=‘" + username + ‘\‘‘ +
", realname=‘" + realname + ‘\‘‘ +
", password=‘" + password + ‘\‘‘ +
", createDate=" + createDate +
", lastLoginTime=" + lastLoginTime +
", enabled=" + enabled +
", accountNonExpired=" + accountNonExpired +
", accountNonLocked=" + accountNonLocked +
", credentialsNonExpired=" + credentialsNonExpired +
", authorities=" + authorities +
‘}‘;
}
}public void testUpdatePassword(){
User user = new User();
user.setUsername("jack");
//哈希算法加密
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
user.setPassword(passwordEncoder.encode("123456"));
userMapper.updatePassword(user);
}SpringSecurity的配置文件
@Configuration
@EnableWebSecurity //启动SpringSecurity过滤器链
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
//该方法的作用就是代替之前配置:<security:authentication-manager>
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("eric").password("123456").authorities("PRODUCT_ADD");
}
//该方法的作用就是代替之前配置:<security:http>
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/product/add").hasAuthority("PRODUCT_ADD")
.antMatchers("/product/update").hasAuthority("PRODUCT_UPDATE")
.antMatchers("/product/list").hasAuthority("PRODUCT_LIST")
.antMatchers("/product/delete").hasAuthority("PRODUCT_DELETE")
.antMatchers("/login").permitAll()
.antMatchers("/**")
.fullyAuthenticated()
.and()
.formLogin().loginPage("/login")
.and()
.csrf().disable();
}
}登录错误处理
@Configuration
public class ErrorPageConfig {
@Bean
public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer(){
return new EmbeddedServletContainerCustomizer(){
//ErrorPage:定义错误页面
//参数一:HttpStatus.FORBIDDEN: 该错误接收什么错误状态码
//参数二:交给哪个请求处理
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.addErrorPages(new ErrorPage(HttpStatus.FORBIDDEN,"/403"));
}
};
}
} 相关推荐
与卿画眉共浮生 2020-11-13
smalllove 2020-11-03
hellowordmonkey 2020-11-02
丽丽 2020-10-30
周太郎 2020-10-28
greensomnuss 2020-10-27
职业炮灰 2020-10-16
与卿画眉共浮生 2020-10-14
feinifi 2020-10-14
feinifi 2020-10-13
yangjinpingc 2020-10-09
davis 2020-09-29
RickyIT 2020-09-27
lisongchuang 2020-09-27
tangxiong0 2020-09-03
meleto 2020-08-17
幸运小侯子 2020-08-14
YangHuiLiang 2020-08-06