配置类继承WebSecurityConfigurerAdapter,并重写其中一个方法:
@Configuration
public class HttpBasicSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic()
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
}
}
测试:
访问login.html,被拦截,要求先登录。用户名为框架默认,密码启动项目时生成:
配置文件中,可以指定密码。
security:
user:
password: admin
name: administrator
其验证时,发送get请求。在请求头携带了此验证信息,其实就是用户名密码base64加密后的字符串。非常容易被破解,不安全。
解密:
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()//防止跨站csrf攻击
.formLogin()
.loginPage("/login.html")//设置登陆页面
.loginProcessingUrl("/login")//form表单对应action地址
.usernameParameter("username")//form表单输入的用户名对应的名称,默认username
.passwordParameter("password")
.defaultSuccessUrl("/index")//登录成功默认跳转路径
.and()
.authorizeRequests()
.antMatchers("/login.html","/login").permitAll()//不需要验证就能访问的资源
.antMatchers("/biz1","/biz2").hasAnyAuthority("ROLE_user","ROLE_admin")//admin user角色访问 ROLE_是ss框
.antMatchers("/syslog","/sysuser").hasAnyAuthority("ROLE_admin")//admin 角色才可访问
.anyRequest().authenticated();
//hasAnyAuthority("ROLE_user","ROLE_admin")等价于hasAnyRole("user","admin"),角色是一种特殊的权限。
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()//内存里面存储用户的身份认证和授权信息。
.withUser("user")
.password(passwordEncoder().encode("123456"))
.roles("user")//方法用于指定用户的角色,一个用户可以有多个角色
.and()
.withUser("admin")
.password(passwordEncoder().encode("123456"))
.roles("admin")
.and()
.passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
public void configure(WebSecurity web) {
//将项目中静态资源路径开放出来
web.ignoring()
.antMatchers( "/css/**", "/fonts/**", "/img/**", "/js/**");//TODO 不知道为什么上边配置不起作用
}
本来,我可以过得很快乐,但是bug害了我。
输入用户名密码,点击登录,访问login时,报302的问题。
我被这个问题坑了一天,查了n多资料都没解决。其实这个不能算是Spring Security的问题。而是因为:
启动项目,访问localhost:8888/index.html。会被成功重定向到login.html,
输入验证信息,访问login时302,之后应该跳转的index.html页面404。
因为其机制是当用户名、密码验证通过后,其默认是重定向到你之前访问的地址。
index.html这个页面,是放在templates目录下的(跟着教程使用了freemarker
模板),必须通过controller访问。所以,根本就不是SpringSecurity的问题!
前边是直接定义了认证后(成功或失败)跳转的页面,现在自定义成功和失败的处理逻辑。
@Component
public class SuccessAuthenticationHandler extends SavedRequestAwareAuthenticationSuccessHandler {
@Value("${spring.security.loginType}")
private String loginType;//以什么形式返回,是给json数据提示还是返回html页面
private static ObjectMapper objectMapper = new ObjectMapper();//对象和json字符串转换,@Response Body底层也是用它
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
if ("JSON".equalsIgnoreCase(loginType)){
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(objectMapper.writeValueAsString(R.success("/index")));
}else{
//跳转到登陆前请求的页面
super.onAuthenticationSuccess(request,response,authentication);
}
}
}
@Component
public class FailureAuthenticationHandler extends SimpleUrlAuthenticationFailureHandler {
private static ObjectMapper objectMapper= new ObjectMapper();
@Value("${spring.security.loginType}")
private String loginType;
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
if ("JSON".equalsIgnoreCase(loginType)){
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(objectMapper.writeValueAsString(R.error(
new CustomException(CustomExceptionType.USER_INPUT_ERROR,"用户信息异常,验证失败!")
)));
}else{
super.onAuthenticationFailure(request,response,exception);
}
}
}
测试通过,目前因为页面没有改造,还是页面跳转的形式。所以,目前认证成功或失败都是返回页面。
如果我们是以json返回数据,而不是HTML的话,就要稍微改造下页面才能测试。
这是之前的页面
修改,使其发送Ajax请求:
formLogin登录方式的登录页
scbg业务系统登录
一分钟后,超时,回到登录页面
再次登录,sessionID已经变化