Spring Security 是 Spring 项目组中用来提供安全认证服务的框架。
安全包括两个主要操作(自己的白话,百度的我看不懂)。
“认证”,即根据数据库中的数据信息判断当前用户是否能够登陆(账号,密码,角色)。
“授权”,指的是判断该用户的角色权限,从而分配其可以访问操作的资源。
Spring Security入门
1.maven集成:
<dependencies>
<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>
</dependencies>
2.配置:
2.1 在web.xml中配置Spring Security的委托代理过滤器DelegatingFilterProxy.class,并引入Spring Security核心配置文件spring-security.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml,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>
注意:这里委托代理过滤器的名称是固定的,只能写springSecurityFilterChain,因为Spring Security框架的底层原理是多个过滤器由一个过滤器链组织依次执行,这个过滤器链就是springSecurityFilterChain,spring容器在DelegatingFilterProxy中要根据这个名称来创建过滤器链bean对象,所以这个名称是固定的。
2.3 spring-security.xml配置
这里我直接写自定义登陆页面的配置,因为是给自己看的,感觉工作时不会用到Spring Security给我们提供的登陆页面。
<?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"/>
<!--第一个属性我也没搞懂,第二个属性时配置忽略SPEL表达式-->
<security:http auto-config="true" use-expressions="false">
<!--自定义登陆页面-->
<security:intercept-url pattern="/**" access="ROLE_ADMIN"></security:intercept-url>
<security:form-login
<!--指定登陆页面-->
login-page="/login.jsp"
<!--指定登陆表单的action请求路径,意思时表单提交给了spring security框架,而不是servlet-->
login-processing-url="/login"
<!--指定表单中username,password对应的name属性的值,默认就是"username","password"-->
username-parameter="username"
password-parameter="password"
<!--配置失败跳转页面-->
authentication-failure-url="/failer.jsp"
<!--配置成功跳转页面-->
authentication-success-forward-url="/pages/main.jsp"
></security:form-login>
<!--关闭 跨站请求伪造 拦截,因为我们使用的自定义页面-->
<security:csrf disabled="true"></security:csrf>
<!--退出,强大的spring security只需配置退出请求路径,就可以帮我们杀死session-->
<security:logout logout-url="/logout.do" invalidate-session="true" logout-success-url="/login.jsp"></security:logout>
</security:http>
<!--认证-->
<security:authentication-manager>
<!--根据数据库进行认证,配置service进行数据库查询-->
<security:authentication-provider user-service-ref="userService">
</security:authentication-provider>
</security:authentication-manager>
</beans>
要让spring security框架为我们进行用户认证,我们定义的userService要实现UserDetailsService接口,实现其UserDetails loadUserByUsername(String username)方法,参数是前端传递过来的username,返回值是一个UserDetails类,这是一个接口,我们用其实现类User对象返回给spring security框架。
2.4 service代码
@Service("userService")
public class UserServiceImpl implements IUserService{//IUserService extends UserDetailsService
@Autowired
private IUserDao userDao;
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//根据username查询对应的UserInfo用户信息
UserInfo userInfo = userDao.findByUsername(username);
//用User类的构造方法创建User对象,这里下面详述
User user = new User(userInfo.getUsername(),"{noop}"+userInfo.getPassword(),getAuthorities(userInfo.getRoles()));
return user;
}
//根据数据库查询回来用户关联的角色信息为user对象最够一个参数赋值
private Collection<? extends GrantedAuthority> getAuthorities(List<Role> roles) {
//使用GrantedAuthority的实现类SimpleGrantedAuthority
Collection<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
for (Role role : roles) {
//SimpleGrantedAuthority的构造方法即需要一个角色名称
authorities.add(new SimpleGrantedAuthority("ROLE_"+role.getRoleName()));
}
return authorities;
}
}
User类的构造方法(源码赋值过来的)
public User(String username, String password, Collection<? extends GrantedAuthority> authorities) {
//调用下面多个参数的构造方法
this(username, password, true, true, true, true, authorities);
}
这里我只关注参数:
public User(String username, String password, boolean enabled, boolean accountNonExpired,
boolean credentialsNonExpired, boolean accountNonLocked,Collection<? extends GrantedAuthority> authorities) {
//......
}
1.String username ---->当前用户名
2.String password ---->密码
3.boolean enabled ---->当前用户是否可用
4.boolean accountNonExpired
5.boolean credentialsNonExpired
6.boolean accountNonLocked
7.Collection<? extends GrantedAuthority> authorities ---->当前用户所关联的角色
这样spring security就可以帮我们对用户,角色,资源权限进行管理了
没写完,改日补全……