简介
springSecurity是一个安全框架,基于 Spring 的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在 Spring 应用上下文中配置的 Bean,充分利用了Spring IoC,DI(控制反转 Inversion of Control ,DI:Dependency Injection 依赖注入)和 AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
1.创建一个maven工程
添加springSecurity所需依赖
org.springframework.security
spring-security-web
4.1.0.RELEASE
org.springframework.security
spring-security-config
4.1.0.RELEASE
2.在WEB-INF中配置web.xml文件
contextConfigLocation
classpath:applicationContext.xml
org.springframework.web.context.ContextLoaderListener
springSecurityFilterChain
org.springframework.web.filter.DelegatingFilterProxy
springSecurityFilterChain
/*
如上filter会拦截所有请求,其中
3.编辑applicationContext.xml配置文件
如上,配置为ROLE_USER角色才能访问目录下的所有资源,认证管理器中配置用户admin为ROLE_USER角色
4.启动工程并访问资源
发现显示如下:
这是因为在配置文件中配置了
5.使用自定义登陆页面
新建登陆页面:
登陆
这里name='username'和name='pasword'默认是这样,如果不想用username和password需要在配置文件进行修改(不建议修改)。这里提交到/login,这个地址是springSecuritu自动生成提供的,并且提交方式为post。
然后修改spring-security.xml配置文件,进行登陆配置,将
default-target-url为登录成功后跳转页面,
authentication-failure-url为登陆失败后跳转页面
login-page:指定登录页面。
配置好后启动工程,发现并不能正常访问,
并且控制台出现了一条有关配置的警告:
警告: Anonymous access to the login page doesn't appear to be enabled. This is almost certainly an error. Please check your configuration allows unauthenticated access to the configured login page. (Simulated access was rejected: org.springframework.security.access.AccessDeniedException: Access is denied)
这是因为在配置
登陆输入用户名密码出现如下错误:
这是因为采用自带的页面是带token的,而我们自定义的页面没有,他的作用是防止csrf拦截,如果想要请求头带token信息必须是jsp页面,html页面无法实现。这里需要关闭csrf。CSRF(Cross-site request forgery)跨站(即跨域,从一个站点请求到另一个站点)请求伪造,也被称为“One Click Attack”或者 Session Riding,通常缩写为 CSRF 或者 XSRF,是一种对网站的恶意利用。
这样就可以正常访问了。
6.使用自定义认证类(一般使用这种方式来认证,毕竟用户名密码角色都是存储在数据库中)
将applicationContext.xml配置文件中认证管理器修改成如下:
编写UserDetailsServiceImpl类实现实现UserDetailsService接口接口(这个接口是spring.security的)
public class UserDetailsServiceImpl implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
List grantedAuths = new ArrayList();
//角色为ROLE_USER,可以将用户的角色查询出来当参数传递进去
grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
//判断用户是否为admin,可以通过用户名查询数据库中存储的用户名和密码
if ("admin".equals(username)) {
//密码是在这里验证的当用户输入123456时就会通过了,将数据库中查询到的密码当入参传入即可
return new User("admin", "123456", grantedAuths);
}
return null;
}
}
这样在UserDetailsServiceImpl类中实现查询数据库的逻辑就可以通过数据库来验证用户名和密码了。