package com.example.security.config;
import com.example.security.handler.MyAccessDeniedHandler;
import com.example.security.handler.MyAuthenticationFailureHandler;
import com.example.security.handler.MyAuthenticationSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyAccessDeniedHandler myAccessDeniedHandler;
/**
* 指定密码加密的方法 * * @return
*/
@Bean
public BCryptPasswordEncoder getPasswordEncode() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
//表单提交
http.formLogin()
// 自定义用户名和密码参数
.usernameParameter("username123")
.passwordParameter("password123")
//自定义登录页面
.loginPage("/login.html")
//必须和表单提交的接口一样,执行自定义登录逻辑
.loginProcessingUrl("/login")
//自定义登录成功处理器
.successHandler(new MyAuthenticationSuccessHandler("/main.html"))
//自定义登录失败处理器
.failureHandler(new MyAuthenticationFailureHandler("/error.html"));
//授权
http.authorizeRequests()
//放行/login.html,不需要认证
.antMatchers("/login.html").permitAll()
// 放行/error.html,不需要认证
.antMatchers("/error.html").permitAll()
//基于权限判断
.antMatchers("/main1.html").hasAuthority("ROLE_1")
//所有请求必须认证
.anyRequest().authenticated();
//异常处理器
http.exceptionHandling().accessDeniedHandler(myAccessDeniedHandler);
//关闭csrf防护
http.csrf().disable();
}
/**
* 放行静态资源,css,js,images * * @param web * @throws Exception
*/
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/css/**", "/js/**").antMatchers("/**/*.png");
}
}
自定义异常处理器
package com.example.security.handler;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* 自定义异常处理器
*/
@Component
public class MyAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
//响应状态403
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.setHeader("Content-Type", "application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write("{status: \"error\",\"msg\": \"权限不足,请联系管理员\"}");
writer.flush();
writer.close();
}
}
自定义登录失败处理器
package com.example.security.handler;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 自定义登录失败处理器
*/
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
private String url;
public MyAuthenticationFailureHandler(String url) {
this.url = url;
}
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
//重定向
response.sendRedirect(url);
}
}
自定义登录成功处理器
package com.example.security.handler;
import com.example.security.pojo.User;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 自定义登录成功处理器
*/
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private String url;
public MyAuthenticationSuccessHandler(String url) {
this.url = url;
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//获取IP地址
System.out.println(request.getRemoteAddr());
//获取认证用户信息
User user = (User) authentication.getPrincipal();
System.out.println("=====" + user.getAuthorities());
//重定向
response.sendRedirect(url);
}
}
User
package com.example.security.pojo;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
public class User implements UserDetails {
private String username;
private String password;
private List authorities;
public User() {
}
public User(String username, String password, List authorities) {
this.username = username;
this.password = password;
this.authorities = authorities;
}
@Override
public Collection extends GrantedAuthority> getAuthorities() {
return this.authorities;
}
@Override
public String getPassword() {
return this.password;
}
@Override
public String getUsername() {
return this.username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
自定义登录逻辑
package com.example.security.service;
import com.example.security.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
/**
* 自定义登录逻辑
*/
@Service
public class UserDetailServiceImpl implements UserDetailsService {
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("=======执行自定义登录逻辑====");
//校验用户名,实际环境中需要从数据库查询
if (!username.equals("admin")) {
throw new UsernameNotFoundException("用户不存在");
}
//比较密码,实际需要从数据库取出原密码校验,框架会自动读取登录页面的密码
String password = bCryptPasswordEncoder.encode("123456");
//返回UserDetails,实际开发中可拓展UserDetails
return new User(username, password,
//自定义权限
AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_1"));
}
}
error.html
Title
登录失败,请重新登录跳转
login.html
登陆
main.html
Title
登录成功!!!
跳转权限页
main1.html
Title
权限控制!!!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)