SpringSecurity在前后端分离项目中的实现
2019-05-25 本文已影响0人
金宝宝的坐骑
一、基本思路
服务端通过 JSON
字符串,告诉前端用户是否登录、认证;前端根据这些提示跳转对应的登录页、认证页
二、具体实现
AuthenticationEntryPoint
:未登录
public class AjaxAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
AjaxResponseBody responseBody = new AjaxResponseBody();
responseBody.setStatus("000");
responseBody.setMsg("无访问权限,请先登录");
httpServletResponse.getWriter().write(JSON.toJSONString(responseBody));
}
}
AuthenticationFailureHandler
:登录失败
public class AjaxAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
AjaxResponseBody responseBody = new AjaxResponseBody();
responseBody.setStatus("400");
responseBody.setMsg("登录失败");
httpServletResponse.getWriter().write(JSON.toJSONString(responseBody));
}
}
AuthenticationSuccessHandler
:登录成功
public class AjaxAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
AjaxResponseBody responseBody = new AjaxResponseBody();
responseBody.setStatus("200");
responseBody.setMsg("登录成功");
httpServletResponse.getWriter().write(JSON.toJSONString(responseBody));
}
}
AccessDeniedHandler
:无权访问
public class AjaxAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
AjaxResponseBody responseBody = new AjaxResponseBody();
responseBody.setStatus("300");
responseBody.setMsg("无权访问");
httpServletResponse.getWriter().write(JSON.toJSONString(responseBody));
}
}
LogoutSuccessHandler
:注销
public class AjaxLogoutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
AjaxResponseBody responseBody = new AjaxResponseBody();
responseBody.setStatus("100");
responseBody.setMsg("注销成功");
httpServletResponse.getWriter().write(JSON.toJSONString(responseBody));
}
}
UserDetails
:定义User对象
public class SelfUserDetails implements UserDetails, Serializable {
private String username;
private String password;
private Set<? extends GrantedAuthority> authorities;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;
}
public void setAuthorities(Set<? extends GrantedAuthority> authorities) {
this.authorities = authorities;
}
@Override
public String getPassword() {
return this.password;
}
@Override
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
UserDetailsService
:用户权限认证
public class SelfUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
SelfUserDetails userInfo = new SelfUserDetails();
userInfo.setUsername(username);
Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder();
String encodePassword = md5PasswordEncoder.encodePassword("123", username);
userInfo.setPassword(encodePassword);
Set authoritiesSet = new HashSet();
GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_ADMIN");
authoritiesSet.add(authority);
userInfo.setAuthorities(authoritiesSet);
return userInfo;
}
}
AuthenticationProvider
:前端交互
public class SelfAuthenticationProvider implements AuthenticationProvider {
@Autowired
SelfUserDetailsService userDetailsService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String userName = (String) authentication.getPrincipal();
String password = (String) authentication.getCredentials();
Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder();
String encodePwd = md5PasswordEncoder.encodePassword(password, userName);
UserDetails userInfo = userDetailsService.loadUserByUsername(userName);
if (!userInfo.getPassword().equals(encodePwd)) {
throw new BadCredentialsException("用户名密码不正确,请重新登陆!");
}
return new UsernamePasswordAuthenticationToken(userName, password, userInfo.getAuthorities());
}
@Override
public boolean supports(Class<?> authentication) {
return true;
}
}
WebSecurityConfigurerAdapter
:登录拦截全局配置
public class SpringSecurityConf extends WebSecurityConfigurerAdapter {
@Autowired
AjaxAuthenticationEntryPoint authenticationEntryPoint; // 未登陆时返回 JSON 格式的数据给前端(否则为 html)
@Autowired
AjaxAuthenticationSuccessHandler authenticationSuccessHandler; // 登录成功返回的 JSON 格式数据给前端(否则为 html)
@Autowired
AjaxAuthenticationFailureHandler authenticationFailureHandler; // 登录失败返回的 JSON 格式数据给前端(否则为 html)
@Autowired
AjaxLogoutSuccessHandler logoutSuccessHandler; // 注销成功返回的 JSON 格式数据给前端(否则为 登录时的 html)
@Autowired
AjaxAccessDeniedHandler accessDeniedHandler; // 无权访问返回的 JSON 格式数据给前端(否则为 403 html 页面)
@Autowired
SelfAuthenticationProvider provider; // 自定义安全认证
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 加入自定义的安全认证
auth.authenticationProvider(provider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.httpBasic().authenticationEntryPoint(authenticationEntryPoint)
.and()
.authorizeRequests()
.anyRequest()
.authenticated()// 其他 url 需要身份认证
.and()
.formLogin() //开启登录
.successHandler(authenticationSuccessHandler) // 登录成功
.failureHandler(authenticationFailureHandler) // 登录失败
.permitAll()
.and()
.logout()
.logoutSuccessHandler(logoutSuccessHandler)
.permitAll();
http.exceptionHandling().accessDeniedHandler(accessDeniedHandler); // 无权访问 JSON 格式的数据
}
}