一.创建工程
这里选上security
二.编写配置类
具体配置方法参照:springSecurity(SSM)
package com.miracle.config;
import com.miracle.security.ImageCodeAuthenticationFilter;
import com.miracle.security.MyAuthenticationFailureHandler;
import com.miracle.security.MyAuthenticationSuccessHandler;
import com.miracle.security.MyUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import javax.sql.DataSource;
/**
* springSecurity配置类
* @EnableWebSecurity:启动springSecurity过滤器链,这个注解已经包含@Configuration
*/
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
// 注入数据源
@Autowired
private DataSource dataSource;
/**
* 该方法的作用就是代替:<security:http> 标签的配置
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
/**
* 定制过滤器(登录时,在验证账号密码前,先验证用户输入验证码是否正确):
* 第一个参数:指定filter
* 第二个参数:指定在哪个filter之前
*/
http.addFilterBefore(imageCodeAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
/**
* 使用formLogin的方式进行认证
* loginPage:指定获取登录页面的url(需要编写controller返回登录页面)
* loginProcessingUrl:指定登录页面中post请求提交到哪里的url(不需要编写controller,框架已实现)
* default-target-url:指定登录成功后,跳转到哪个url(需要编写controller)
* successHandler:指定登录成功后,由哪个类来进行处理
* failureHandler:指定登录失败后,由哪个类来进行处理
* username-parameter:指定登录表单中用户名的input中name值,如果这里不配置,则默认为username
* password-parameter:指定登录表单中密码的input中name值,如果这里不配置,则默认为password
*/
http.formLogin().loginPage("/login").loginProcessingUrl("/securityLogin")
.successHandler(myAuthenticationSuccessHandler())
.failureHandler(myAuthenticationFailureHandler());
// 关闭跨域请求
http.csrf().disable();
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry interceptUrlRegistry = http.authorizeRequests();
// 配置页面拦截规则 begin
/**
* pattern:需要拦截的资源 /* 代表根目录下的一级目录 /** 代表根目录下的所有目录
* 注意!!!:由于是拦截器链机制,<security:intercept-url> 的编写顺序要求
* access:拦截方式
* isFullyAuthenticated():该资源需要认证才可以访问
* isAnonymous():只有匿名用户可以访问,登录用户不可访问
* permitAll():该资源可以所有用户访问
*/
// 放行静态资源
interceptUrlRegistry.antMatchers("/js/**").permitAll();
// 放行首页,登录页,验证码
interceptUrlRegistry.antMatchers("/login","/imageCode","/product/index").permitAll();
interceptUrlRegistry.antMatchers("/product/add").hasAuthority("ROLE_ADD_PRODUCT");
interceptUrlRegistry.antMatchers("/product/update").hasAuthority("ROLE_UPDATE_PRODUCT");
interceptUrlRegistry.antMatchers("/product/list").hasAuthority("ROLE_LIST_PRODUCT");
interceptUrlRegistry.antMatchers("/product/delete").hasAuthority("ROLE_DELETE_PRODUCT");
// 拦截剩余所有页面 需要登录
interceptUrlRegistry.antMatchers("/**").fullyAuthenticated();
// 配置页面拦截规则 end
/**
* 加上Remember Me功能
* tokenRepository:指定持久层对象操作 存放 Remember Me 数据表信息
* tokenValiditySeconds:有效时间(秒)
*/
http.rememberMe().tokenRepository(jdbcTokenRepository()).tokenValiditySeconds(604800);
/**
* 注销功能
* logoutUrl("/logout"):springSecurity内LogoutFilter要拦截的url(向这个url发送请求来注销)
* logoutSuccessUrl("/login"):用户退出后要被重定向的url
* invalidateHttpSession:默认为true,用户在退出后Http session失效
* logoutSuccessHandler():指定一个bean(需要实现LogoutSuccessHandler接口),用来自定义退出成功后的操作
*/
http.logout().logoutUrl("/logout").logoutSuccessUrl("/login").invalidateHttpSession(true);
/**
* accessDeniedPage:当用户访问权限不足时,跳转到指定url(需要编写controller返回权限不足的页面)
* accessDeniedHandler:定义bean来处理当用户访问权限不足时的情况
*/
http.exceptionHandling().accessDeniedPage("/accessDeny");
}
/**
* 该方法的作用就是代替:<security:authentication-manager>
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
/*
userDetailsService:设置认证用户提供类
passwordEncoder:设置密码配置的实现类
*/
auth.userDetailsService(myUserDetailsService()).passwordEncoder(bCryptPasswordEncoder());
}
// springSecurity登录失败处理类,注册到IOC容器
@Bean
public MyAuthenticationFailureHandler myAuthenticationFailureHandler(){
return new MyAuthenticationFailureHandler();
}
// springSecurity登录成功处理类,注册到IOC容器
@Bean
public MyAuthenticationSuccessHandler myAuthenticationSuccessHandler(){
return new MyAuthenticationSuccessHandler();
}
/**
* 创建 springSecurity 密码加密工具类
* 是 PasswordEncoder 接口的实现,也可以使用其他实现
*/
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
/**
* springSecurity实现 remember me 功能:
* 如果用户登录选择 remember me ,springSecurity会将其cookie值存入数据库,来实现remember me 功能
* JdbcTokenRepositoryImpl 用来存取cookie值
*
* jdbcTokenRepository.setDataSource(dataSource):指定数据源
* jdbcTokenRepository.setCreateTableOnStartup(true):当项目启动时,springSecurity创建表存储remember me相关信息,第二次启动时要注释这个属性
*/
@Bean
public JdbcTokenRepositoryImpl jdbcTokenRepository(){
JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
jdbcTokenRepository.setDataSource(dataSource);
// jdbcTokenRepository.setCreateTableOnStartup(true);
return jdbcTokenRepository;
}
/**
* 添加过滤器,加入到springSecurity过滤器链之前,处理用户输入的验证码是否正确
* 如果用户验证码输入正确:拦截放行,交给springSecurity过滤器链处理
* 如果用户验证码输入错误:转向MyAuthenticationFailureHandler进行处理
*/
@Bean
public ImageCodeAuthenticationFilter imageCodeAuthenticationFilter(){
return new ImageCodeAuthenticationFilter();
}
/**
* 用户信息提供类
*/
@Bean
public MyUserDetailsService myUserDetailsService(){
return new MyUserDetailsService();
}
}