Heim  >  Artikel  >  Java  >  So implementieren Sie die Überprüfung mit SpringBoot+SpringSecurity+jwt

So implementieren Sie die Überprüfung mit SpringBoot+SpringSecurity+jwt

WBOY
WBOYnach vorne
2023-05-24 20:07:131663Durchsuche

Umgebung

  • springBoot 2.3.3

  • springSecurity 5.0

  • jjwt 0.91

pox.xml Datei main.information

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

Verzeichnis Strukturinformationen

Bitte ignorieren Sie die Dateibenennung

So implementieren Sie die Überprüfung mit SpringBoot+SpringSecurity+jwt

jwtAccessDeniedHandler und JwtAuthenticationEntryPoint

Die Funktionen dieser beiden Klassen sind Klassen zur Verarbeitung von Fehlern, damit Benutzer auf nicht autorisierte Ressourcen zugreifen und Fehlertokens verwenden können. Sie müssen sie nur in der Sicherheitskonfigurationsdatei konfigurieren

/**
 * @author Bxsheng
 * @blogAddress www.kdream.cn
 * @createTIme 2020/9/17
 * since JDK 1.8
 * 当用户在没有授权的时候,返回的指定信息
 */
@Component
public class jwtAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
        System.out.println("用户访问没有授权资源");
        System.out.println(e.getMessage());
        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, e==null?"用户访问没有授权资源":e.getMessage());

    }
}
/**
 * @author Bxsheng
 * @blogAddress www.kdream.cn
 * @createTIme 2020/9/17
 * since JDK 1.8
 */
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        System.out.println("用户访问资源没有携带正确的token");
        System.out.println(e.getMessage());
        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, e==null?"用户访问资源没有携带正确的token":e.getMessage());

    }
}

UserDetailsServiceImpl Überprüfung der Anmeldeinformationen

Diese Klasse erbt direkt UserDetailsService zur Überprüfung der Anmeldeinformationen. Wenn Sie zum Anmelden das Kontokennwort eingeben, betreten Sie diese Klasse, um die Informationen zu überprüfen.

Natürlich verwende ich hier direkt das fest codierte Passwort. Normalerweise sollten die Benutzerinformationen und Berechtigungsinformationen aus der Datenbank abgerufen werden Anmeldeberechtigungen implementieren Control (Code))]((https://www.yisu.com/article/257119.htm) Die Klasse im Artikel.

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {

        //直接写死数据信息,可以在这里获取数据库的信息并进行验证

        UserDetails userDetails  = User.withUsername(s).password(new BCryptPasswordEncoder().encode("123456"))
                .authorities("bxsheng").build();
        return userDetails;
    }
}

JwtAuthenticationFilter Benutzerdefiniertes Überprüfungs-JWT

Diese Klasse verwendet direkt Slyhs [ SpringBoot +JWT implementiert die Anmeldeberechtigungskontrolle (Code)]((https://www.yisu.com/article/257119.htm)) Die Klasse im Artikel.

Die Hauptfunktion dieser Klasse besteht darin, JWT-Informationen zu überprüfen. Sie überträgt hauptsächlich die Token-Anfrage, analysiert das JWT und setzt es in den Sicherheitskontext. Einer der Zwecke dieses Ansatzes besteht darin, die im Token enthaltenen Berechtigungsinformationen im Kontext zu speichern. Sie können Benutzer authentifizieren Informationen, und die anderen beiden sind so eingerichtet, dass ein Berechtigungszugriff erforderlich ist.

package cn.kdream.securityjwt.utlis;

import io.jsonwebtoken.*;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Bxsheng
 * @blogAddress www.kdream.cn
 * @createTIme 2020/9/16
 * since JDK 1.8
 */
public class JwtTokenUtils {
    public static final String TOKEN_HEADER = "Authorization";
    public static final String TOKEN_PREFIX = "Bearer ";
    public static final String SECRET = "jwtsecret";
    public static final String ISS = "echisan";

    private static final Long EXPIRATION = 60 * 60 * 3L; //过期时间3小时

    private static final String ROLE = "role";

    //创建token
    public static String createToken(String username, String role, boolean isRememberMe){
        Map map = new HashMap();
        map.put(ROLE, role);
        return Jwts.builder()
                .signWith(SignatureAlgorithm.HS512, SECRET)
                .setClaims(map)
                .setIssuer(ISS)
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION * 1000))
                .compact();
    }

    //从token中获取用户名(此处的token是指去掉前缀之后的)
    public static String getUserName(String token){
        String username;
        try {
            username = getTokenBody(token).getSubject();
        } catch (    Exception e){
            username = null;
        }
        return username;
    }

    public static String getUserRole(String token){
        return (String) getTokenBody(token).get(ROLE);
    }

    private static Claims getTokenBody(String token){
        Claims claims = null;
        try{
            claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
        } catch(ExpiredJwtException e){
            e.printStackTrace();
        } catch(UnsupportedJwtException e){
            e.printStackTrace();
        } catch(MalformedJwtException e){
            e.printStackTrace();
        } catch(SignatureException e){
            e.printStackTrace();
        } catch(IllegalArgumentException e){
            e.printStackTrace();
        }
        return claims;
    }

    //是否已过期
    public static boolean isExpiration(String token){
        try{
            return getTokenBody(token).getExpiration().before(new Date());
        } catch(Exception e){
            System.out.println(e.getMessage());
        }
        return true;
    }
}
Effekt

Direkter Zugriff auf Benutzerinformationen, die eine Autorisierung erfordern

Token abrufen

Greifen Sie auf die Anmeldemethode in der Startup-Klasse zu, um Token-Informationen abzurufen

Da ich ein festes Passwort verwende, kann ich beim Zugriff mit dem falschen Passwort im globalen Springboot darauf zugreifen. Die Ausnahmeinformationen werden erfasst während der Ausnahmebehandlung

/**
 * @author Bxsheng
 * @blogAddress www.kdream.cn
 * @createTIme 2020/9/16
 * since JDK 1.8
 */
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String tokenHeader = request.getHeader(JwtTokenUtils.TOKEN_HEADER);
        //如果请求头中没有Authorization信息则直接放行了
        if(tokenHeader == null || !tokenHeader.startsWith(JwtTokenUtils.TOKEN_PREFIX)){
            chain.doFilter(request, response);
            return;
        }
        //如果请求头中有token,则进行解析,并且设置认证信息
        if(!JwtTokenUtils.isExpiration(tokenHeader.replace(JwtTokenUtils.TOKEN_PREFIX,""))){
            //设置上下文
            UsernamePasswordAuthenticationToken authentication = getAuthentication(tokenHeader);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        super.doFilterInternal(request, response, chain);
    }

    //获取用户信息
    private UsernamePasswordAuthenticationToken getAuthentication(String tokenHeader){
        String token = tokenHeader.replace(JwtTokenUtils.TOKEN_PREFIX, "");
        String username = JwtTokenUtils.getUserName(token);
        // 获得权限 添加到权限上去
        String role = JwtTokenUtils.getUserRole(token);
        List<GrantedAuthority> roles = new ArrayList<GrantedAuthority>();
        roles.add(new GrantedAuthority() {
            @Override
            public String getAuthority() {
                return role;
            }
        });
        if(username != null){
            return new UsernamePasswordAuthenticationToken(username, null,roles);
        }
        return null;
    }

}

Erhalten Sie das Token korrekt und führen Sie den Zugriff auf geschützte Ressourcen durch

Es enthält hartcodierte bxsheng-Berechtigungsinformationen, sodass die von bxsheng identifizierten Ressourceninformationen normal abgerufen werden können.

Informationen erfolgreich abgerufenSo implementieren Sie die Überprüfung mit SpringBoot+SpringSecurity+jwt

Versuchen Sie, nicht autorisierte Ressourceninformationen abzurufen

Das obige ist der detaillierte Inhalt vonSo implementieren Sie die Überprüfung mit SpringBoot+SpringSecurity+jwt. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen