Spring Security 基于java类的配置小案例
Spring Security是基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案。其java配置十分简单,让我们一起来看一下吧。
准备
准备一个maven的web工程,导入Spring Security的坐标jar包:
<--pom.xml文件片段-->
<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>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
开始
一、配置过滤器
/*
创建 SecurityWebApplicationInitializer 类继承 AbstractSecurityWebApplicationInitializer
不用重写任何方法,即等于在web.xml中配置了如下设置
<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>
*/
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
//在非springmvc项目中需要重写该类的无参构造,如下
/* public SecurityWebApplicationInitializer(){
super(WebSecurityConfig.class);
}
springmvc项目则不用
*/
}
二、编写Spring Security配置类
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
/*
该bean是实现了 UserDetailsService 接口的实现类
从数据库取值进行验证信息
*/
@Autowired
private UserService userService;
/*
该方法就是对比XML配置中的主要配置。
这是链式编程,初看可能不太明白。多阅读几遍就好了。
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()//该方法所返回的对象的方法来配置请求级别的安全细节
.antMatchers("/login.jsp", "/failer.jsp","/css/**","/js/**","/plugins/**").permitAll()//对于登录路径不进行拦截
.antMatchers("/**").hasAnyRole("USER")//表示登录成功允许过的权限,hasAnyRole方法会给权限添加“ROLE_”的前缀,XML中则需要写完整
.and()
.formLogin()//配置登录页面
.loginPage("/login.jsp")//登录页面的访问路径
.loginProcessingUrl("/login.do")//登录页面下表单提交的路径
.failureUrl("/failer.jsp")//登录失败后跳转的路径
.defaultSuccessUrl("/index.jsp")//登录成功后默认跳转的路径
.and()
.csrf().disable()//关闭跨域请求。该设置不当,有可能一直出现403(无论是否有访问权)
.logout()//用户退出操作
.invalidateHttpSession(true)//销毁 session 域对象
.logoutUrl("/logout.do")//用户退出所访问的路径,需要使用Post方式
.logoutSuccessUrl("/login.jsp")
.permitAll()
.and()
.rememberMe()//启用记住我功能
.tokenValiditySeconds(2419200);
}
//配置Spring Security的Filter链,如果没有可以不用重写
/* @Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
}*/
//配置user-detail服务
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService)
.passwordEncoder(new BCryptPasswordEncoder());//密码加密方式
}
}
附上相同配置的XML的描述
<?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"/>
<!--
配置具体的规则
auto-config="true" 不用自己编写登录的页面,框架提供默认登录页面
use-expressions="false" 是否使用SPEL表达式(没学习过)
-->
<security:http auto-config="true" use-expressions="false">
<!-- 配置具体的拦截的规则 pattern="请求路径的规则" access="访问系统的人,必须有ROLE_USER的角色" -->
<security:intercept-url pattern="/**" access="ROLE_USER"/>
<!-- 定义跳转的具体的页面 -->
<security:form-login
login-page="/login.jsp"
login-processing-url="/login.do"
default-target-url="/index.jsp"
authentication-failure-url="/failer.jsp"
authentication-success-forward-url="/pages/main.jsp"
/>
<!-- 关闭跨域请求 -->
<security:csrf disabled="true"/>
<!-- 退出 -->
<security:logout invalidate-session="true" logout-url="/logout.do" logout-success-url="/login.jsp" />
</security:http>
<!-- 切换成数据库中的用户名和密码 -->
<security:authentication-manager>
<security:authentication-provider user-service-ref="userService">
<!-- 配置加密的方式
<security:password-encoder ref="passwordEncoder"/>-->
</security:authentication-provider>
</security:authentication-manager>
<!-- 配置加密类 -->
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
</beans>
三、加载 Spring Security配置类
/*
springMVC基于java配置的 “片段”
*/
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
// Spring IoC容器配置
@Override
protected Class<?>[] getRootConfigClasses() {
// Spring的Java配置类数组
return new Class<?>[]{SpringConfig.class,
/*spring Security配置类放在该处,当项目启动时即可加载到pring Security配置类*/WebSecurityConfig.class};
}
}
PS:
本小案例是从数据库获取信息验证,需要实现 UserDetailsService 接口
/*
附上 UserDetailsService 实现类的 “片段”
*/
public class UserServiceImpl implements UserDetailsService {
@Autowired
private UserDao userDao;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
//根据用户名查询用户信息
UserInfo userInfo = userDao.findByUsername(s);
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
for (Role role : userInfo.getRoles()) {
authorities.add(new SimpleGrantedAuthority(role.getRoleName()));
}
return new User(userInfo.getUsername(), userInfo.getPassword(),
userInfo.getStatus() == 1, true,
true, true,
authorities);
}
}
结束
献上小小思路,抛砖引玉,还望大神们指教。