SpringSecurity框架入门
目录
1 、Spring Security框架入门
1.1 Spring Security简介
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
1.2 Spring Security入门小Demo
1.2.1 SpringSecurity入门Demo
1.2.1.1 创建工程spring-security-demo1 ,pom.xml内容
pom.xml
<?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.itheima</groupId>
<artifactId>springsecurity-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<spring.security.version>4.2.4.RELEASE</spring.security.version>
<servlet-api.version>3.0.1</servlet-api.version>
<jstl.version>1.2</jstl.version>
<commons-logging.version>1.2</commons-logging.version>
</properties>
<dependencies>
<!--日志包-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${commons-logging.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>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas</artifactId>
<version>${spring.security.version}</version>
</dependency>
<!--JSP-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
</dependencies>
</project>
1.2.1.2 创建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_3_1.xsd"
version="3.1">
<!--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配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<!--Spring监听-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
1.2.1.3 创建html和jsp
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
第一个SpringSecurity应用
</body>
</html>
error.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>异常处理</title>
</head>
<body>
您无权访问该页面
</body>
</html>
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form name='f' action='/login' method='POST'>
<table>
<tr><td>User:</td><td><input type='text' name='username' value=''></td></tr>
<tr><td>Password:</td><td><input type='password' name='password'/></td></tr>
<tr><td colspan='2'><input name="submit" type="submit" value="Login"/></td></tr>
</table>
</form>
</body>
</html>
创建pages/1.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
pages下的jsp
</body>
</html>
创建jsp/1.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
jsp下的jsp
</body>
</html>
1.2.1.4 创建spring配置文件 spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--包扫描-->
<context:component-scan base-package="com" />
</beans>
1.2.1.5 创建SpringSecurityConfig配置类
该类需要继承WebSecurityConfigurerAdapter,并且该类需要加上@EnableWebSecurity注解,该类里面通常要写3个方法:
忽略某些配置的方法
public void configure(WebSecurity web) throws Exception {}
配置对应地址拦截请求的方法,例如拦截地址、关闭csrf、
protected void configure(HttpSecurity http) throws Exception {}
授权用户,比如创建某些账号,某些账号就可以登录了
protected void configure(AuthenticationManagerBuilder auth) throws Exception {}
实现代码:
@Component
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
/***
* 忽略安全过滤
* @param web
* @throws Exception
*/
@Override
public void configure(WebSecurity web) throws Exception {
//忽略相关地址
web.ignoring().antMatchers("/images/**");
web.ignoring().antMatchers("/js/**");
web.ignoring().antMatchers("/login.html");
web.ignoring().antMatchers("/error.html");
}
/***
* 请求拦截配置
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
//拦截规则配置
http.authorizeRequests()
.antMatchers("/pages/**").access("hasRole('ADMIN')") //ADMIN角色可以访问/pages/下的所有文件
.antMatchers("/jsp/**").access("hasRole('USER')") //USER角色可以访问/jsp/下的所有文件
.and().formLogin().loginPage("/login.html").loginProcessingUrl("/login") //指定登录页和处理登录的地址
.and().logout().logoutUrl("/logout").invalidateHttpSession(true); //指定登出页和登出后让session无效
//关闭CSRF安全策略
http.csrf().disable();
//异常处理,例如403
http.exceptionHandling().accessDeniedPage("/error.html");
//只允许一个用户登录,如果同一个账户两次登录,那么第一个账户将被踢下线,跳转到登录页面
http.sessionManagement().maximumSessions(1).expiredUrl("/login.html");
}
/***
* 创建用户并授权
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//创建一个用户存在内存中,账号是admin,密码是123456,角色是ROLE_ADMIN
auth.inMemoryAuthentication().withUser("admin").password("123456").roles("ADMIN");
auth.inMemoryAuthentication().withUser("xiaohong").password("123456").roles("USER");
}
}
1.2.1.6 自定义认证类
上面的账号密码写死了,很多时候我们需要自己写认证类,代码如下:
@Component
public class UserDetailsServiceImpl implements UserDetailsService {
/***
* 自定义认证类
* @param username
* @return
* @throws UsernameNotFoundException
*/
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//根据用户名去数据库中查询用户信息,这里不做演示,模拟已经查询出结果
String password="123456"; //密码
//用户授权信息
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
return new User(username,password,authorities);
}
}
修改SpringSecurityConfig配置类
/***
* UserDetailsServiceImpl是UserDetailsService的实现类,这里可以直接注入进来
*/
@Autowired
private UserDetailsService userDetailsService;
/***
* 创建用户并授权
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//创建一个用户存在内存中,账号是admin,密码是123456,角色是ROLE_ADMIN
//auth.inMemoryAuthentication().withUser("admin").password("123456").roles("ADMIN");
//auth.inMemoryAuthentication().withUser("xiaohong").password("123456").roles("USER");
//注册自定义认证类
auth.userDetailsService(userDetailsService);
}