Spring Boot OAuth2:从cookie中提取JWT进行身份验证

时间:2018-07-17 02:56:06

标签: java spring spring-boot oauth-2.0 jwt

我正在使用Spring Boot为我的应用程序构建一个简单的身份验证过程。 我有AuthorizationServerConfig和ResourceServerConfig设置,我的前端是SPA。当我点击/ oauth / token路由时,我得到了一个先前存储在localStorage中的JWT,当我尝试点击资源服务器路由时,我使用此JWT设置了授权标头,一切正常。

但是现在我想对存储在cookie中的JWT进行授权,如何配置它,使其与我当前的授权/资源服务器配置一起使用?我搜索了一段时间,我能找到的最好的方法是设置一个自定义令牌提取器,但是我不确定如何正确设置它,谢谢。

--------------更新--------------

我启用了@EnableAuthorizationServer和@EnableResourceServer,并且EnableResourceServer自动设置了OAuthAuthenticationProcessingFilter,此过滤器用户承载标头身份验证使用承载令牌提取器从请求标头中提取,我查看了源代码,并将其硬编码到库中,如何自定义此过滤器以从Cookie中提取JWT?

2 个答案:

答案 0 :(得分:-1)

从请求对象读取cookie值并手动解析jwt。 这是示例代码

public Jws<Claims> parseJWT(HttpServletRequest request) {
    Cookie cookie =  WebUtils.getCookie(request, "Token cookie name");
    if(cookie == null) {
        throw new SecurityException("Token not found from cookies");
    }
    String token  = cookie.getValue();
    return Jwts.parser().setSigningKey("your signing Key").parseClaimsJws(token);
}

您可以创建请求过滤器并检查jwt。

答案 1 :(得分:-1)

JWT有许多实现。正在使用这个。 <ck-editor style="height: 1000px;" name="editor1" [config]="CkeditorConfig" [(ngModel)]="something.modal" skin="moono-lisa" language="en" [fullPage]="true"></ck-editor>

我要添加一个令牌助手类,该类具有验证,生成和刷新令牌的方法。您可以专注于JWT提取部分。

Jar依赖性

io.jsonwebtoken

JWT帮助程序类。它包含验证,刷新和生成令牌的方法。

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.0</version>
</dependency>

最后是控制器类

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

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

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import com.test.dfx.common.TimeProvider;
import com.test.dfx.model.LicenseDetail;
import com.test.dfx.model.User;


@Component
public class TokenHelper {

    protected final Log LOGGER = LogFactory.getLog(getClass());

    @Value("${app.name}")
    private String APP_NAME;

    @Value("${jwt.secret}")
    public String SECRET;    //  Secret key used to generate Key. Am getting it from propertyfile

    @Value("${jwt.expires_in}")
    private int EXPIRES_IN;  //  can specify time for token to expire. 

    @Value("${jwt.header}")
    private String AUTH_HEADER;


    @Autowired
    TimeProvider timeProvider;

    private SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS512;  // JWT Algorithm for encryption


    public Date getIssuedAtDateFromToken(String token) {
        Date issueAt;
        try {
            final Claims claims = this.getAllClaimsFromToken(token);
            issueAt = claims.getIssuedAt();
        } catch (Exception e) {
            LOGGER.error("Could not get IssuedDate from passed token");
            issueAt = null;
        }
        return issueAt;
    }

    public String getAudienceFromToken(String token) {
        String audience;
        try {
            final Claims claims = this.getAllClaimsFromToken(token);
            audience = claims.getAudience();
        } catch (Exception e) {
            LOGGER.error("Could not get Audience from passed token");
            audience = null;
        }
        return audience;
    }

    public String refreshToken(String token) {
        String refreshedToken;
        Date a = timeProvider.now();
        try {
            final Claims claims = this.getAllClaimsFromToken(token);
            claims.setIssuedAt(a);
            refreshedToken = Jwts.builder()
                .setClaims(claims)
                .setExpiration(generateExpirationDate())
                .signWith( SIGNATURE_ALGORITHM, SECRET )
                .compact();
        } catch (Exception e) {
            LOGGER.error("Could not generate Refresh Token from passed token");
            refreshedToken = null;
        }
        return refreshedToken;
    }

    public String generateToken(String username) {
        String audience = generateAudience();
        return Jwts.builder()
                .setIssuer( APP_NAME )
                .setSubject(username)
                .setAudience(audience)
                .setIssuedAt(timeProvider.now())
                .setExpiration(generateExpirationDate())
                .signWith( SIGNATURE_ALGORITHM, SECRET )
                .compact();
    }



    private Claims getAllClaimsFromToken(String token) {
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(SECRET)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            LOGGER.error("Could not get all claims Token from passed token");
            claims = null;
        }
        return claims;
    }

    private Date generateExpirationDate() {
        long expiresIn = EXPIRES_IN;
        return new Date(timeProvider.now().getTime() + expiresIn * 1000);
    }

    public int getExpiredIn() {
        return EXPIRES_IN;
    }

    public Boolean validateToken(String token, UserDetails userDetails) {
        User user = (User) userDetails;
        final String username = getUsernameFromToken(token);
        final Date created = getIssuedAtDateFromToken(token);
        return (
                username != null &&
                username.equals(userDetails.getUsername()) &&
                        !isCreatedBeforeLastPasswordReset(created, user.getLastPasswordResetDate())
        );
    }

    private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset) {
        return (lastPasswordReset != null && created.before(lastPasswordReset));
    }

    public String getToken( HttpServletRequest request ) {
        /**
         *  Getting the token from Authentication header
         *  e.g Bearer your_token
         */
        String authHeader = getAuthHeaderFromHeader( request );
        if ( authHeader != null && authHeader.startsWith("Bearer ")) {
            return authHeader.substring(7);
        }

        return null;
    }

    public String getAuthHeaderFromHeader( HttpServletRequest request ) {
        return request.getHeader(AUTH_HEADER);
    }


}