一晒屎、基本思路
服務端通過 JSON
字符串喘蟆,告訴前端用戶是否登錄、認證鼓鲁;前端根據(jù)這些提示跳轉對應的登錄頁履肃、認證頁
二、具體實現(xiàn)
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 格式的數(shù)據(jù)給前端(否則為 html)
@Autowired
AjaxAuthenticationSuccessHandler authenticationSuccessHandler; // 登錄成功返回的 JSON 格式數(shù)據(jù)給前端(否則為 html)
@Autowired
AjaxAuthenticationFailureHandler authenticationFailureHandler; // 登錄失敗返回的 JSON 格式數(shù)據(jù)給前端(否則為 html)
@Autowired
AjaxLogoutSuccessHandler logoutSuccessHandler; // 注銷成功返回的 JSON 格式數(shù)據(jù)給前端(否則為 登錄時的 html)
@Autowired
AjaxAccessDeniedHandler accessDeniedHandler; // 無權訪問返回的 JSON 格式數(shù)據(jù)給前端(否則為 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 格式的數(shù)據(jù)
}
}