引入依赖
1 2 3 4 5 6 7 8 9 10
   | <dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-security</artifactId> </dependency>
  <dependency>     <groupId>org.springframework.security</groupId>     <artifactId>spring-security-test</artifactId>     <scope>test</scope> </dependency>
   | 
 
SpringSecurity 配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
   | @EqualsAndHashCode(callSuper = true) @Data @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true) @ConfigurationProperties(prefix = "spring.security.ignore") public class WebSecurityConfig extends WebSecurityConfigurerAdapter {     private List<String[]> marchers;
      @Bean     public UserService userService(){         return new UserService();     }
      @Override     protected void configure(HttpSecurity http) throws Exception {         http                 .anonymous().disable()                 .csrf().disable()                 .authorizeRequests()
                  .anyRequest().authenticated()                 .and()                 .formLogin()
                  .loginProcessingUrl("/login")                 .successHandler(authenticationSuccessHandler())                 .failureHandler(authenticationFailureHandler())                 .permitAll()                 .and()                 .logout()                 .invalidateHttpSession(true)                 .deleteCookies("JSESSIONID")                 .logoutSuccessHandler(new LogoutSuccess())                 .permitAll()                 .and()                 .sessionManagement()                 .invalidSessionStrategy(new InvalidSessionStrategyImpl())                 .maximumSessions(-1).expiredSessionStrategy(expiredSessionStrategy())                 .sessionRegistry(sessionRegistry())                 .and()                 .and()                 .exceptionHandling()                 .authenticationEntryPoint(new UnauthenticatedEntryPoint())                 .accessDeniedHandler(new AuthorizationFailure())                 .and()                 .addFilterBefore(new AuthorizationFilter(new AuthorizationMetadataSource(), new                 AuthorizationAccessDecisionManager()), FilterSecurityInterceptor.class);
      }
      @Override     public void configure(AuthenticationManagerBuilder auth) {         auth.authenticationProvider(authenticationProvider());     }
      @Bean     public SessionRegistry sessionRegistry(){         return new SessionRegistryImpl();     }
      @Bean     public ExpiredSessionStrategyImpl expiredSessionStrategy(){         return new ExpiredSessionStrategyImpl();     }
      @Bean     public BCryptPasswordEncoder passwordEncoder() {         return SecurityUtils.getPasswordEncoder();     }
      @Override     public void configure(WebSecurity web) {         for (String[] marcher : marchers) {             web.ignoring().antMatchers(marcher);         }     }
      @Bean     public DaoAuthenticationProvider authenticationProvider() {         DaoAuthenticationProvider provider = new DaoAuthenticationProvider();                  provider.setHideUserNotFoundExceptions(false);         provider.setUserDetailsService(userService());         provider.setPasswordEncoder(passwordEncoder());         return provider;     }
      @Bean     public AuthenticationSuccess authenticationSuccessHandler(){         return new AuthenticationSuccess();     }
      @Bean     public AuthenticationFailureHandler authenticationFailureHandler(){         return new AuthenticationFailure();     } }
 
   | 
 
自定义 userService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
   | public class UserService implements UserDetailsService {     @Autowired     private WebSecurityConfig securityConfig;
      @Autowired     private SysUserMapper userMapper;
      @Override     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {         if (StringUtils.isEmpty(username)) {             throw new UsernameNotFoundException("用户名不能为空!");         }         SysUser user = new SysUser();         user.setLoginName(username);         SysUser queryUser = userMapper.selectOne(user);         if (null == queryUser) {             throw new UsernameNotFoundException("用户  " + username + " 不存在!");         }         if (!queryUser.getPermissionIpList().contains("0.0.0.0") && !queryUser.getPermissionIpList().contains                 (SecurityUtils.getRemoteAddress())) {             throw new InvalidIpAddrException("登录 IP 地址不合法");         }
          return new SecurityUser(queryUser);     }
      
 
      public void reAuthorization(){         SecurityUser user = SecurityUtils.currentUser();         assert user != null;         String username = user.getUsername();         user.setRoles(userMapper.findRolesByName(username));         user.setMenus(userMapper.findMenusByName(username));         user.setFunctions(userMapper.findFunctionsByName(username));
          List<GrantedAuthority> authorities = new ArrayList<>();         for (Function function : user.getFunctions()) {             for (String url : function.getFunctionUrl().split(",")) {                 authorities.add(new SimpleGrantedAuthority(url));             }         }         user.setAuthorities(authorities.stream().distinct().collect(Collectors.toList()));                  Authentication auth = SecurityUtils.getAuthentication();                  Authentication newAuth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), authorities);                  SecurityContextHolder.getContext().setAuthentication(newAuth);
      }
 
      
 
 
      public void kickOutUser(String... userNames) {         SessionRegistry sessionRegistry = securityConfig.sessionRegistry();         for (Object o : sessionRegistry.getAllPrincipals()) {             SecurityUser user = (SecurityUser) o;             for (String username : userNames) {                 if (user.getLoginName().equals(username)) {                     for (SessionInformation sessionInformation : sessionRegistry.getAllSessions(user, false)) {                         sessionInformation.expireNow();                     }                 }             }         }     } }
  | 
 
用户实体类 SecurityUser
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
   | @Data public class SecurityUser extends SysUser implements UserDetails{
           private List<SysRole> roles;
           private List<Menu> menus;
           private List<Function> functions;
      private Collection<? extends GrantedAuthority> authorities;
      SecurityUser(SysUser user) {         this.setUserId(user.getUserId());         this.setGlbm(user.getGlbm());         this.setXh(user.getXh());         this.setLoginName(user.getLoginName());         this.setLoginPassword(user.getLoginPassword());         this.setPermissionIpList(user.getPermissionIpList());         this.setLatestLoginTime(user.getLatestLoginTime());         this.setTotalLoginCounts(user.getTotalLoginCounts());         this.setName(user.getName());         this.setCreateTime(user.getCreateTime());         this.setUpdateTime(user.getUpdateTime());     }
 
      @Override     public Collection<? extends GrantedAuthority> getAuthorities() {         return authorities;     }
      @Override     public boolean isAccountNonExpired() {         return true;     }
      @Override     public boolean isAccountNonLocked() {         return true;     }
      @Override     public boolean isCredentialsNonExpired() {         return true;     }
      @Override     public boolean isEnabled() {         return true;     }
      @Override     public String getPassword() {         return super.getLoginPassword();     }
      @Override     public String getUsername() {         return super.getLoginName();     }
      @Override     public int hashCode() {         return this.getLoginName().hashCode();     }
      @Override     public boolean equals(Object obj) {         return obj instanceof SecurityUser && ((SecurityUser) obj).getLoginName().equals(this.getLoginName());     } }
   | 
 
授权Filter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
   | public class AuthorizationFilter extends AbstractSecurityInterceptor implements Filter {
      private AuthorizationMetadataSource metadataSource;
      public AuthorizationFilter(AuthorizationMetadataSource metadataSource, AuthorizationAccessDecisionManager             accessDecisionManager) {         this.metadataSource = metadataSource;         this.setAccessDecisionManager(accessDecisionManager);     }
      @Override     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)             throws IOException, ServletException {         FilterInvocation fi = new FilterInvocation(servletRequest, servletResponse, filterChain);         invoke(fi);     }
      private void invoke(FilterInvocation fi) throws IOException, ServletException {         InterceptorStatusToken token = super.beforeInvocation(fi);         try {             fi.getChain().doFilter(fi.getRequest(), fi.getResponse());         } finally {             super.afterInvocation(token, null);         }     }
 
      @Override     public Class<?> getSecureObjectClass() {         return FilterInvocation.class;     }
      @Override     public SecurityMetadataSource obtainSecurityMetadataSource() {         return metadataSource;     }
      @Override     public void destroy() {     }
      @Override     public void init(FilterConfig filterConfig) {     } }
  | 
 
授权访问决策器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
   | public class AuthorizationAccessDecisionManager implements AccessDecisionManager {
      
 
      @Override     public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)             throws AccessDeniedException, InsufficientAuthenticationException {         HttpServletRequest request = ((FilterInvocation) object).getRequest();         String url = ((FilterInvocation) object).getRequestUrl();         for (GrantedAuthority grantedAuthority : authentication.getAuthorities()) {             SimpleGrantedAuthority authority = (SimpleGrantedAuthority) grantedAuthority;             if (matches(authority.getAuthority(), request)) {                 return;             }         }         throw new AccessDeniedException("uri: " + url + ",无权限访问!");     }
      
 
      @Override     public boolean supports(ConfigAttribute attribute) {         return true;     }
      
 
      @Override     public boolean supports(Class<?> clazz) {         return true;     }
      private boolean matches(String url, HttpServletRequest request) {         AntPathRequestMatcher matcher = new AntPathRequestMatcher(url);         return matcher.matches(request);     } }
  | 
 
授权元数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
   | public class AuthorizationMetadataSource implements FilterInvocationSecurityMetadataSource {
      
 
 
 
 
      @Override     public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {         String url = ((FilterInvocation) object).getRequestUrl();         Collection<ConfigAttribute> configAttributes = new ArrayList<>();         configAttributes.add(new SecurityConfig(url));         return configAttributes;     }
      
 
 
      @Override     public Collection<ConfigAttribute> getAllConfigAttributes() {         return null;     }
      @Override     public boolean supports(Class<?> clazz) {         return true;     } }
  | 
 
封装一些 Security 工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
   | public class SecurityUtils {
      public static Authentication getAuthentication(){         return SecurityContextHolder.getContext().getAuthentication();     }
      
 
 
      public static boolean isAuthenticated(){         return getAuthentication() != null || !(getAuthentication() instanceof AnonymousAuthenticationToken);     }
      
 
 
      public static SecurityUser currentUser(){         if (isAuthenticated()) {             return (SecurityUser) getAuthentication().getPrincipal();         }         return null;     }
      
 
      private static WebAuthenticationDetails webAuthenticationDetails(){         return (WebAuthenticationDetails)getAuthentication().getDetails();     }
      
 
      public static String getSessionId(){         return webAuthenticationDetails().getSessionId();     }
      
 
      public static String getRemoteAddress(){         return webAuthenticationDetails().getRemoteAddress();     }
      
 
 
      public static BCryptPasswordEncoder getPasswordEncoder(){         return new BCryptPasswordEncoder(4);     }
      
 
 
 
      public static String createPassword(String rawPassword){         return getPasswordEncoder().encode(rawPassword.trim());     }
      
 
 
 
 
      public static boolean isMatching(String rawPassword,String encodedPassword){         return getPasswordEncoder().matches(rawPassword,encodedPassword);     }
  }
  | 
 
主要的实现类都列举在内了,还有一些成功和失败的处理类,再次没有列举出来
因为该项目为构建纯restful风格的后台项目,这些成功或失败的处理类基本都是返回的http状态码