ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【Spring Security】

2021-08-04 20:01:31  阅读:194  来源: 互联网

标签:String Spring private token tokenManager Security public redisTemplate


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

<dependencies>

    <dependency>

        <groupId>com.atguigu</groupId>

        <artifactId>common_utils</artifactId>

        <version>0.0.1-SNAPSHOT</version>

    </dependency>

    

    <!-- Spring Security依赖 -->

    <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-security</artifactId>

    </dependency>

    <dependency>

        <groupId>io.jsonwebtoken</groupId>

        <artifactId>jjwt</artifactId>

    </dependency>

</dependencies>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


/**

 * <p>

 * Security配置类

 * </p>

 */

@Configuration

@EnableWebSecurity

@EnableGlobalMethodSecurity(prePostEnabled = true)

public class TokenWebSecurityConfig extends WebSecurityConfigurerAdapter {


    private UserDetailsService userDetailsService;

    private TokenManager tokenManager;

    private DefaultPasswordEncoder defaultPasswordEncoder;
    private RedisTemplate redisTemplate;

    @Autowired
    public TokenWebSecurityConfig(UserDetailsService userDetailsService, DefaultPasswordEncoder defaultPasswordEncoder,

                                  TokenManager tokenManager, RedisTemplate redisTemplate) {

        this.userDetailsService = userDetailsService;

        this.defaultPasswordEncoder = defaultPasswordEncoder;

        this.tokenManager = tokenManager;

        this.redisTemplate = redisTemplate;

    }

    /**

     * 配置设置

     * @param http

     * @throws Exception

     */

    @Override

    protected void configure(HttpSecurity http) throws Exception {

        http.exceptionHandling()

                .authenticationEntryPoint(new UnauthorizedEntryPoint())

                .and().csrf().disable()

                .authorizeRequests()

                .anyRequest().authenticated()

                .and().logout().logoutUrl("/admin/acl/index/logout")

                .addLogoutHandler(new TokenLogoutHandler(tokenManager,redisTemplate)).and()

                .addFilter(new TokenLoginFilter(authenticationManager(), tokenManager, redisTemplate))

                .addFilter(new TokenAuthenticationFilter(authenticationManager(), tokenManager, redisTemplate)).httpBasic();

    }

    /**

     * 密码处理

     * @param auth

     * @throws Exception

     */

    @Override

    public void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(userDetailsService).passwordEncoder(defaultPasswordEncoder);

    }

    /**

     * 配置哪些请求不拦截

     * @param web

     * @throws Exception

     */

    @Override
    public void configure(WebSecurity web) throws Exception {

        web.ignoring().antMatchers("/api/**",

                "/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**"

               );

    }

}

在这里插入图片描述



import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;


/**

 * <p>

 * 密码的处理方法类型

 * </p>

 */

@Component
public class DefaultPasswordEncoder implements PasswordEncoder {

    public DefaultPasswordEncoder() {

        this(-1);

    }

    /**

    * @param strength

     *            the log rounds to use, between 4 and 
     */

    public DefaultPasswordEncoder(int strength) {

    }

    public String encode(CharSequence rawPassword) {

        return MD5.encrypt(rawPassword.toString());

    }

    public boolean matches(CharSequence rawPassword, String encodedPassword) {

        return encodedPassword.equals(MD5.encrypt(rawPassword.toString()));

    }

}

在这里插入图片描述

import io.jsonwebtoken.CompressionCodecs;

import io.jsonwebtoken.Jwts;

import io.jsonwebtoken.SignatureAlgorithm;

import org.springframework.stereotype.Component;


import java.util.Date;


/**

 * <p>

 * token管理

 * </p>

 */

@Component
public class TokenManager {


    private long tokenExpiration = 24*60*60*1000;

    private String tokenSignKey = "123456";

    public String createToken(String username) {

        String token = Jwts.builder().setSubject(username)

                .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration))

                .signWith(SignatureAlgorithm.HS512, tokenSignKey).compressWith(CompressionCodecs.GZIP).compact();

        return token;

    }


    public String getUserFromToken(String token) {

        String user = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token).getBody().getSubject();

        return user;

    }

    public void removeToken(String token) {

        //jwttoken无需删除,客户端扔掉即可。

    }

}

在这里插入图片描述

/**

 * <p>

 * 登出业务逻辑类

 * </p>

 */

public class TokenLogoutHandler implements LogoutHandler {

    private TokenManager tokenManager;

    private RedisTemplate redisTemplate;

    public TokenLogoutHandler(TokenManager tokenManager, RedisTemplate redisTemplate) {

        this.tokenManager = tokenManager;

        this.redisTemplate = redisTemplate;

    }

    @Override

    public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {

        String token = request.getHeader("token");

        if (token != null) {

            tokenManager.removeToken(token);

            //清空当前用户缓存中的权限数据

            String userName = tokenManager.getUserFromToken(token);

            redisTemplate.delete(userName);

        }

        ResponseUtil.out(response, R.ok());

    }

}

在这里插入图片描述

/**

 * <p>

 * 未授权的统一处理方式

 * </p>

 */

public class UnauthorizedEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,

                         AuthenticationException authException) throws IOException, ServletException {

        ResponseUtil.out(response, R.error());

    }

}

在这里插入图片描述


/**

 * <p>

 * 安全认证用户详情信息

 * </p>

 */

@Data

@Slf4j

public class SecurityUser implements UserDetails {

    //当前登录用户

    private transient User currentUserInfo;

    //当前权限

    private List<String> permissionValueList;

    public SecurityUser() {

    }


    public SecurityUser(User user) {

        if (user != null) {

            this.currentUserInfo = user;

        }

    }

    @Override

    public Collection<? extends GrantedAuthority> getAuthorities() {

        Collection<GrantedAuthority> authorities = new ArrayList<>();

        for(String permissionValue : permissionValueList) {

            if(StringUtils.isEmpty(permissionValue)) continue;

            SimpleGrantedAuthority authority = new SimpleGrantedAuthority(permissionValue);

            authorities.add(authority);

        }

        return authorities;

    }

    @Override

    public String getPassword() {

        return currentUserInfo.getPassword();

    }

    @Override

    public String getUsername() {

        return currentUserInfo.getUsername();

    }

    @Override
    public boolean isAccountNonExpired() {

        return true;

    }

    @Override
    public boolean isAccountNonLocked() {

        return true;

    }

    @Override
    public boolean isCredentialsNonExpired() {

        return true;

    }

    @Override

    public boolean isEnabled() {

        return true;

    }

}

在这里插入图片描述

/**

 * <p>

 * 用户实体类

 * </p>

 */

@Data

@ApiModel(description = "用户实体类")

public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "微信openid")

    private String username;

    @ApiModelProperty(value = "密码")

    private String password;

    @ApiModelProperty(value = "昵称")
    private String nickName;

    @ApiModelProperty(value = "用户头像")

    private String salt;

    @ApiModelProperty(value = "用户签名")

    private String token;

}

在这里插入图片描述

/**

 * <p>

 * 登录过滤器,继承UsernamePasswordAuthenticationFilter,对用户名密码进行登录校验

 * </p>

 */

public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {

    private AuthenticationManager authenticationManager;

    private TokenManager tokenManager;

    private RedisTemplate redisTemplate;

    public TokenLoginFilter(AuthenticationManager authenticationManager, TokenManager tokenManager, RedisTemplate redisTemplate) {

        this.authenticationManager = authenticationManager;

        this.tokenManager = tokenManager;

        this.redisTemplate = redisTemplate;

        this.setPostOnly(false);

        this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/admin/acl/login","POST"));

    }

    @Override

    public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)

            throws AuthenticationException {

        try {

            User user = new ObjectMapper().readValue(req.getInputStream(), User.class);


            return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), new ArrayList<>()));

        } catch (IOException e) {

            throw new RuntimeException(e);

        }


    }


    /**

     * 登录成功

     * @param req

     * @param res

     * @param chain

     * @param auth

     * @throws IOException

     * @throws ServletException

     */

    @Override
    protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain,

                                            Authentication auth) throws IOException, ServletException {

        SecurityUser user = (SecurityUser) auth.getPrincipal();

        String token = tokenManager.createToken(user.getCurrentUserInfo().getUsername());

        redisTemplate.opsForValue().set(user.getCurrentUserInfo().getUsername(), user.getPermissionValueList());

        ResponseUtil.out(res, R.ok().data("token", token));

    }

    /**

     * 登录失败

     * @param request

     * @param response

     * @param e

     * @throws IOException

     * @throws ServletException

     */

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,

                                              AuthenticationException e) throws IOException, ServletException {

        ResponseUtil.out(response, R.error());

    }

}

在这里插入图片描述


/**

 * <p>

 * 访问过滤器

 * </p>

 */

public class TokenAuthenticationFilter extends BasicAuthenticationFilter {

    private TokenManager tokenManager;

    private RedisTemplate redisTemplate;


    public TokenAuthenticationFilter(AuthenticationManager authManager, TokenManager tokenManager,RedisTemplate redisTemplate) {

        super(authManager);

        this.tokenManager = tokenManager;

        this.redisTemplate = redisTemplate;

    }


    @Override

    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)

            throws IOException, ServletException {

        logger.info("================="+req.getRequestURI());

        if(req.getRequestURI().indexOf("admin") == -1) {

            chain.doFilter(req, res);

            return;

        }


        UsernamePasswordAuthenticationToken authentication = null;

        try {

            authentication = getAuthentication(req);

        } catch (Exception e) {

            ResponseUtil.out(res, R.error());

        }

        if (authentication != null) {

            SecurityContextHolder.getContext().setAuthentication(authentication);

        } else {

            ResponseUtil.out(res, R.error());

        }

        chain.doFilter(req, res);

    }

    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {

        // token置于header里

        String token = request.getHeader("token");

        if (token != null && !"".equals(token.trim())) {

            String userName = tokenManager.getUserFromToken(token);

            List<String> permissionValueList = (List<String>) redisTemplate.opsForValue().get(userName);

            Collection<GrantedAuthority> authorities = new ArrayList<>();

            for(String permissionValue : permissionValueList) {

                if(StringUtils.isEmpty(permissionValue)) continue;

                SimpleGrantedAuthority authority = new SimpleGrantedAuthority(permissionValue);

                authorities.add(authority);

            }

            if (!StringUtils.isEmpty(userName)) {

                return new UsernamePasswordAuthenticationToken(userName, token, authorities);

            }

            return null;

        }

        return null;

    }

}

标签:String,Spring,private,token,tokenManager,Security,public,redisTemplate
来源: https://blog.csdn.net/m0_46495243/article/details/119384204

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有