SpringSecurity
安全访问控制解决方案的安全框架 登录控制
SpringSecurity https://www.cnblogs.com/qiantao/p/14605154.html
登录 http://localhost:9091/user/login form表单提交 username password 没有登录,请求会跳转到登录页面 密码错误,跳转失败页面
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.6.4</version>
</dependency>
<dependency><!--json-->
<groupId>org.nutz</groupId>
<artifactId>nutz</artifactId>
<version>1.r.62</version>
</dependency>
/**
* ringSecurity安全框架配置
*/
@Configuration
@EnableWebSecurity//开启Spring Security的功能
//prePostEnabled属性决定Spring Security在接口前注解是否可用@PreAuthorize,@PostAuthorize等注解,设置为true,会拦截加了这些注解的接口
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfg extends WebSecurityConfigurerAdapter {
@Resource
private AuthenticationSuccessHandler loginSuccessHandler; //认证成功结果处理器
@Resource
private AuthenticationFailureHandler loginFailureHandler; //认证失败结果处理器
//http请求拦截配置
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().frameOptions().disable();//开启运行iframe嵌套页面
http//1、配置权限认证
.authorizeRequests()
//配置不拦截路由
.antMatchers("/500").permitAll()
.antMatchers("/403").permitAll()
.antMatchers("/404").permitAll()
.antMatchers("/login").permitAll()
.anyRequest() //任何其它请求
.authenticated() //都需要身份认证
.and()
//2、登录配置表单认证方式
.formLogin()
.loginPage("http://www.baidu.com")//自定义登录页面的url /login
.usernameParameter("username")//设置登录账号参数,与表单参数一致
.passwordParameter("password")//设置登录密码参数,与表单参数一致
// 告诉Spring Security在发送指定路径时处理提交的凭证,默认情况下,将用户重定向回用户来自的页面。登录表单form中action的地址,也就是处理认证请求的路径,
// 只要保持表单中action和HttpSecurity里配置的loginProcessingUrl一致就可以了,也不用自己去处理,它不会将请求传递给Spring MVC和您的控制器,所以我们就不需要自己再去写一个/user/login的控制器接口了
.loginProcessingUrl("/user/login")//配置默认登录入口
.defaultSuccessUrl("/index")//登录成功后默认的跳转页面路径
.failureUrl("/login?error=true")
.successHandler(loginSuccessHandler)//使用自定义的成功结果处理器
.failureHandler(loginFailureHandler)//使用自定义失败的结果处理器
.and()
//3、注销
.logout()
.logoutUrl("/logout")
.logoutSuccessHandler(new CustomLogoutSuccessHandler())
.permitAll()
.and()
//4、session管理
.sessionManagement()
.invalidSessionUrl("/login") //失效后跳转到登陆页面
//单用户登录,如果有一个登录了,同一个用户在其他地方登录将前一个剔除下线
//.maximumSessions(1).expiredSessionStrategy(expiredSessionStrategy())
//单用户登录,如果有一个登录了,同一个用户在其他地方不能登录
//.maximumSessions(1).maxSessionsPreventsLogin(true) ;
.and()
//5、禁用跨站csrf攻击防御
.csrf()
.disable();
}
@Override
public void configure(WebSecurity web) throws Exception {
//配置静态文件不需要认证
web.ignoring().antMatchers("/static/**");
}
/**
* 指定加密方式
*/
@Bean
public PasswordEncoder passwordEncoder(){
// 使用BCrypt加密密码
return new BCryptPasswordEncoder();
}
@Component
public class CustomUserDetailsService implements UserDetailsService {
@Resource
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
/**
* 1/通过userName 获取到userInfo信息
* 2/通过User(UserDetails)返回details。
*/
//通过userName获取用户信息
// UserInfo userInfo = userInfoService.getUserInfoByUsername(userName);
UserInfo userInfo = new UserInfo("xmh","123","admin");
if(userInfo == null) {
throw new UsernameNotFoundException("not found");
}
//定义权限列表.
List<GrantedAuthority> authorities = new ArrayList<>();
// 用户可以访问的资源名称(或者说用户所拥有的权限) 注意:必须"ROLE_"开头
authorities.add(new SimpleGrantedAuthority("ROLE_"+ userInfo.getRole()));
User userDetails = new User(userInfo.getUserName(),passwordEncoder.encode(userInfo.getPassword()),authorities);
return userDetails;
}
}
/**
* @Description 登录成功处理
*/
@Component("loginSuccessHandler")
public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
@Resource
private ObjectMapper objectMapper;
private RequestCache requestCache;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {
// 获取前端传到后端的全部参数
Enumeration enu = request.getParameterNames();
while (enu.hasMoreElements()) {
String paraName = (String) enu.nextElement(); System.out.println("参数- " + paraName + " : " + request.getParameter(paraName));
}
logger.info("登录认证成功");
//这里写你登录成功后的逻辑,可以验证其他信息,如验证码等。
response.setContentType("application/json;charset=UTF-8");
Map resultObj = new HashMap<>();
resultObj.put("code", HttpStatus.OK.value());
resultObj.put("msg","登录成功");
resultObj.put("authentication",objectMapper.writeValueAsString(authentication));
response.getWriter().write(Json.toJson(resultObj));
// this.getRedirectStrategy().sendRedirect(request, response, "/index");//重定向
}
}
/**
* @Description 登录失败处理
*/
@Component("loginFailureHandler")
public class LoginFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Resource
private ObjectMapper objectMapper;
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
logger.info("登录失败");
this.saveException(request, exception);
//this.getRedirectStrategy().sendRedirect(request, response, "/login?error=true");
response.setContentType("application/json;charset=UTF-8");
Map resultObj = new HashMap<>();
resultObj.put("code", "01");
resultObj.put("msg","login fail 失败");
response.getWriter().write(Json.toJson(resultObj));
}
}
public class CustomLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
System.out.println("注销成功!");
//这里写你登录成功后的逻辑
response.setStatus(HttpStatus.OK.value());
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write("注销成功!");
}
}
@GetMapping("/hello")
@ResponseBody
public String hello() {
System.out.println("*****hello****");
return "hello";
}

浙公网安备 33010602011771号