留一份前后分离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

 

posted @ 2021-05-09 20:11  顶风少年  阅读(75)  评论(0编辑  收藏  举报
返回顶部