zoukankan      html  css  js  c++  java
  • 留一份前后分离SpringSecurity基础配置

    <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>RELEASE</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
    View Code
    package com.datang.bingxiang.ss;
    
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.stereotype.Component;
    
    
    //加密解密
    @Component
    public class DefaultPasswordEncoder implements PasswordEncoder{
    
        //加密
        @Override
        public String encode(CharSequence rawPassword) {
            return rawPassword.toString();
        }
    
        //比较
        @Override
        public boolean matches(CharSequence rawPassword, String encodedPassword) {
            // TODO Auto-generated method stub
            return encodedPassword.equals(rawPassword.toString());
        }
        
    }
    View Code
    package com.datang.bingxiang.ss;
    
    import java.util.HashMap;
    
    import org.springframework.stereotype.Component;
    
    //模拟redis
    @Component
    public class RedisClient {
    
        
        private HashMap<String,Object> map = new HashMap();
        
        
        public void add(String key,Object value) {
            map.put(key, value);
        }
        
        
        public void remove(String key) {
            map.remove(key);
        }
        
        public Object get(String key) {
            return map.get(key);
        }
    }
    View Code
    package com.datang.bingxiang.ss;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.HashMap;
    
    import javax.servlet.http.HttpServletResponse;
    
    import com.alibaba.fastjson.JSONObject;
    
    //返回值
    public class ResponseUtil {
        public static void out(HttpServletResponse response) {
            HashMap<String, Object> r = new HashMap<>();
            r.put("status", "200");
            r.put("msg", "退出成功");
            r.put("data", null);
    
            try {
                response.setCharacterEncoding("UTF-8");
                response.setStatus(200);
                PrintWriter writer = response.getWriter();
                writer.write(JSONObject.toJSONString(r));
                writer.flush();
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
        public static void authSucc(HttpServletResponse response, String token) {
            HashMap<String, Object> r = new HashMap<>();
            r.put("status", "200");
            r.put("msg", "认证成功");
            r.put("data", token);
    
            try {
                response.setCharacterEncoding("UTF-8");
                response.setStatus(200);
                PrintWriter writer = response.getWriter();
                writer.write(JSONObject.toJSONString(r));
                writer.flush();
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
        public static void unAuth(HttpServletResponse response) {
            HashMap<String, Object> r = new HashMap<>();
            r.put("status", "405");
            r.put("msg", "未授权");
            r.put("data", null);
    
            try {
                response.setCharacterEncoding("UTF-8");
                response.setStatus(200);
                PrintWriter writer = response.getWriter();
                writer.write(JSONObject.toJSONString(r));
                writer.flush();
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
        public static void authErr(HttpServletResponse response) {
            HashMap<String, Object> r = new HashMap<>();
            r.put("status", "406");
            r.put("msg", "认证失败");
            r.put("data", null);
    
            try {
                response.setCharacterEncoding("UTF-8");
                response.setStatus(200);
                PrintWriter writer = response.getWriter();
                writer.write(JSONObject.toJSONString(r));
                writer.flush();
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
        public static void noPermiss(HttpServletResponse response) {
            HashMap<String, Object> r = new HashMap<>();
            r.put("status", "407");
            r.put("msg", "权限不足");
            r.put("data", null);
    
            try {
                response.setCharacterEncoding("UTF-8");
                response.setStatus(200);
                PrintWriter writer = response.getWriter();
                writer.write(JSONObject.toJSONString(r));
                writer.flush();
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    }
    View Code
    package com.datang.bingxiang.ss;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;
    //用户对象
    public class SecurityUser implements UserDetails{
    
        private String username;
        
        private String password;
        
        private Collection<GrantedAuthority> permissionValueList;
        
        
        
        
        
    
        public Collection<GrantedAuthority> getPermissionValueList() {
            return permissionValueList;
        }
    
        public void setPermissionValueList(Collection<GrantedAuthority> permissionValueList) {
            this.permissionValueList = permissionValueList;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
        
        
        //-----------------------------------
    
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return permissionValueList;
        }
    
        @Override
        public String getPassword() {
            // TODO Auto-generated method stub
            return password;
        }
    
        @Override
        public String getUsername() {
            // TODO Auto-generated method stub
            return username;
        }
    
        @Override
        public boolean isAccountNonExpired() {
            // TODO Auto-generated method stub
            return true;
        }
    
        @Override
        public boolean isAccountNonLocked() {
            // TODO Auto-generated method stub
            return true;
        }
    
        @Override
        public boolean isCredentialsNonExpired() {
            // TODO Auto-generated method stub
            return true;
        }
    
        @Override
        public boolean isEnabled() {
            // TODO Auto-generated method stub
            return true;
        }
    
    }
    View Code
    package com.datang.bingxiang.ss;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class TestController {
    
        @GetMapping("a")
        public String a() {
            return "a-----success";
        }
    
        @GetMapping("b")
        public String b() {
            return "b-----success";
        }
    
        @GetMapping("c")
        public String c() {
            return "c-----success";
        }
    }
    View Code
    package com.datang.bingxiang.ss;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.security.access.AccessDeniedException;
    import org.springframework.security.web.access.AccessDeniedHandler;
    //权限不足
    public class TokenAccessDeniedHandler implements AccessDeniedHandler{
    
        @Override
        public void handle(HttpServletRequest request, HttpServletResponse response,
                AccessDeniedException accessDeniedException) throws IOException, ServletException {
            ResponseUtil.noPermiss(response);
        }
    
    }
    View Code
    package com.datang.bingxiang.ss;
    
    import java.io.IOException;
    import java.util.List;
    
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.tomcat.util.modeler.BaseAttributeFilter;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
    
    //授权过滤器
    public class TokenAuthFilter extends BasicAuthenticationFilter {
    
        
        private TokenManager tokenManager;
    
        private RedisClient redis;
        
    
        public TokenAuthFilter(AuthenticationManager authenticationManager,TokenManager tokenManager,RedisClient redisClient) {
            super(authenticationManager);
            this.tokenManager = tokenManager;
            this.redis = redisClient;
        }
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            String token = request.getHeader("token");
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = null;
            if (token != null) {
                String username = tokenManager.getUserInfoFromToken(token);
                List<GrantedAuthority> permissionValueList = (List<GrantedAuthority>) redis.get(username);
                usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(username, token,
                        permissionValueList);
            }
            if(usernamePasswordAuthenticationToken!=null) {
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
            chain.doFilter(request, response);
        }
    }
    View Code
    package com.datang.bingxiang.ss;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
    import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
    
    //认证过滤器
    public class TokenLoginFileter extends UsernamePasswordAuthenticationFilter {
    
        private AuthenticationManager authenticationManager;
        private TokenManager tokenManager;
        private RedisClient redisClient;
    
        public TokenLoginFileter(AuthenticationManager authenticationManagerm,TokenManager tokenManager,RedisClient redisClient) {
            this.setPostOnly(false);
            this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login", "POST"));
            this.authenticationManager = authenticationManagerm;
            this.redisClient = redisClient;
            this.tokenManager = tokenManager;
        }
    
        @Override
        public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
                throws AuthenticationException {
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            return authenticationManager
                    .authenticate(new UsernamePasswordAuthenticationToken(username, password, new ArrayList()));
        }
    
        @Override
        protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
                Authentication authResult) throws IOException, ServletException {
            SecurityUser securityUser = (SecurityUser) authResult.getPrincipal();
    
            String username = securityUser.getUsername();
            String password = securityUser.getPassword();
            Collection<GrantedAuthority> permissionValueList = securityUser.getPermissionValueList();
    
            String token = tokenManager.createToken(username);
    
            redisClient.add(username, permissionValueList);
    
            ResponseUtil.authSucc(response, token);
        }
    
        @Override
        protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                AuthenticationException failed) throws IOException, ServletException {
            ResponseUtil.authErr(response);
        }
    }
    View Code
    package com.datang.bingxiang.ss;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.web.authentication.logout.LogoutHandler;
    
    //退出登录
    public class TokenLogoutHandler implements LogoutHandler {
    
        private TokenManager tokenManager;
    
        private RedisClient redis;
    
        TokenLogoutHandler(TokenManager tokenManager, RedisClient redis) {
            this.tokenManager = tokenManager;
            this.redis = redis;
        }
    
        @Override
        public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
            String token = request.getHeader("token");
    
            if (token != null) {
                String username = tokenManager.getUserInfoFromToken(token);
                redis.remove(username);
                ResponseUtil.out(response);
            } else {
                ResponseUtil.unAuth(response);
            }
    
        }
    
    }
    View Code
    package com.datang.bingxiang.ss;
    
    import java.util.Date;
    
    import org.springframework.stereotype.Component;
    
    import io.jsonwebtoken.Claims;
    import io.jsonwebtoken.Jws;
    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.SignatureAlgorithm;
    
    //token
    @Component
    public class TokenManager {
    
        //创建token
        public String createToken(String username) {
            String secret = "1111";
            String token = Jwts.builder().setHeaderParam("h1", "v1")// head
                    .setHeaderParam("h2", "v2")// head
                    .claim("userName", username)// body-内容
                    .claim("22222", "222222222")// body-内容
                    .setIssuer("顶风少年")// body-签发者
                    .setSubject("全体客户")// body-面向用户
                    .setAudience("接收人xxx")// body-接收者
                    .setIssuedAt(new Date())// body-签发时间
                    .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60))// body-过期时间
                    .setNotBefore(new Date(System.currentTimeMillis() + 100))// body-不能再这个时间之前访问
                    .signWith(SignatureAlgorithm.HS256, secret)// 对head和body进行签名
                    .compact();
            return token;
        }
    
        //获取用户名
        public String getUserInfoFromToken(String token) {
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey("1111").parseClaimsJws(token);
            return (String) claimsJws.getBody().get("userName");
        }
    }
    View Code
    package com.datang.bingxiang.ss;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    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.config.http.SessionCreationPolicy;
    
    @Configuration
    public class TokenWebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private UserDetailsServiceImpl userDetailsServiceImpl;
        @Autowired
        private TokenManager tokenManager;
        @Autowired
        private RedisClient redisClient;
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            //禁用session
            http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
            http.exceptionHandling()
                    .authenticationEntryPoint(new UnauthEntryPoint())// 未授权
                    .accessDeniedHandler(new TokenAccessDeniedHandler())//权限不足
                    .and().csrf().disable()
                    .authorizeRequests()
                    .antMatchers("/b").hasAnyAuthority("m1")
                    .antMatchers("/c").hasAnyAuthority("m3")
                    .anyRequest().authenticated()
                    .and()
                    .logout().logoutUrl("/out")// 退出路径
                    .addLogoutHandler(new TokenLogoutHandler(tokenManager, redisClient))
                    .and()
                    .addFilter(new TokenLoginFileter(authenticationManager(), tokenManager, redisClient))
                    .addFilter(new TokenAuthFilter(authenticationManager(), tokenManager, redisClient));
        }
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(userDetailsServiceImpl).passwordEncoder(new DefaultPasswordEncoder());
        }
    
        @Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/a");
        }
    }
    View Code
    package com.datang.bingxiang.ss;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.web.AuthenticationEntryPoint;
    
    //未授权
    public class UnauthEntryPoint implements AuthenticationEntryPoint{
        
        @Override
        public void commence(HttpServletRequest request, HttpServletResponse response,
                AuthenticationException authException) throws IOException, ServletException {
            ResponseUtil.unAuth(response);
        }
    
    }
    View Code
    package com.datang.bingxiang.ss;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.List;
    
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.stereotype.Service;
    //查询用户和权限
    @Service
    public class UserDetailsServiceImpl implements UserDetailsService {
    
        HashMap<String, String> userMap = new HashMap<>();
    
        HashMap<String, List<String>> permissMap = new HashMap<>();
    
        public UserDetailsServiceImpl() {
            userMap.put("bbb", "bbb");
            userMap.put("ccc", "ccc");
    
            permissMap.put("bbb", Arrays.asList("m1", "m2"));
            permissMap.put("ccc", Arrays.asList("m3", "m4"));
        }
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            String password = userMap.get(username);
            if (password == null) {
                throw new UsernameNotFoundException("用户不存在");
            }
            
            
            
            SecurityUser user = new SecurityUser();
            user.setUsername(username);
            user.setPassword(password);
            
            List<String> permissionValueList = permissMap.get(username);
            if(permissionValueList!=null) {
                Collection<GrantedAuthority> authorities = new ArrayList<>();
                for(String permissionValue:permissionValueList) {
                    SimpleGrantedAuthority authority = new SimpleGrantedAuthority(permissionValue);
                    authorities.add(authority);
                }
                user.setPermissionValueList(authorities);
            }
            
            return user;
        }
    
    }
    View Code
  • 相关阅读:
    python 通过*.cer *..pfx 获取公钥私钥
    python 交集 并集 差集
    python3 RSA加密、解密、签名
    Go 入门
    ansible入门篇一
    ACM/ICPC 之 两道dijkstra练习题(ZOJ1053(POJ1122)-ZOJ1053)
    数学软件 之 基于MATLAB的DFP算法
    ACM/ICPC 之 最短路径-dijkstra范例(ZOJ2750-POJ1135(ZOJ1298))
    ACM/ICPC 之 判别MST唯一性-Kruskal解法(POJ1679)
    ACM/ICPC 之 四道MST-Prim解法(POJ1258-POJ1751-POJ2349-POJ3026)
  • 原文地址:https://www.cnblogs.com/zumengjie/p/14748706.html
Copyright © 2011-2022 走看看