下面列出了怎么用io.jsonwebtoken.SignatureAlgorithm的API类实例代码及写法,或者点击链接到github查看源代码。
@Before
public void before(){
String pk = org.apache.commons.codec.binary.Base64.encodeBase64String(keyPair.getPublic().getEncoded());
stubFor(get("/oauth2/publickey").willReturn(aResponse().withStatus(200).withBody(pk)));
JwtBuilder builder = jwtBuilder(System.currentTimeMillis()+3600*1000L)
.signWith(SignatureAlgorithm.RS256,keyPair.getPrivate());
jwtToken = builder.compact();
SSOConfig config = new SSOConfig().autoConfigureUrls(baseUrl);
config.setClientId("test");
config.setClientSecret("test_secret");
config.setResourceName("resourceName");
config.setRedirectUri("http://www.example.com");
client = new SSOClient(config);
basicHeader = SSOUtils.encodeBasicAuthorizationHeader(config.getClientId(),config.getClientSecret());
}
private Key resolveSigningKey(final JwsHeader header) {
final LineApiResponse<JWKSet> response = apiClient.getJWKSet();
if (!response.isSuccess()) {
Log.e(TAG, "failed to get LINE JSON Web Key Set [JWK] document.");
return null;
}
final JWKSet jwkSet = response.getResponseData();
final String keyId = header.getKeyId();
final JWK jwk = jwkSet.getJWK(keyId);
if (jwk == null) {
Log.e(TAG, "failed to find Key by Id: " + keyId);
return null;
}
final String algorithm = header.getAlgorithm();
final SignatureAlgorithm alg = SignatureAlgorithm.forName(algorithm);
if (alg.isEllipticCurve()) {
return generateECPublicKey(jwk);
}
throw new SecurityException("Unsupported signature algorithm '" + algorithm + '\'');
}
/**
* 构建JWT对象
* @param expire
* @param user
* @return
*/
public static String buildJwt(Date expire, UserVO user) {
String jwt = Jwts.builder()
// 使用HS256加密算法
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
// 过期时间
.setExpiration(expire)
.claim("loginName",user.getLoginName())
.claim("nickName",user.getNickName())
.claim("phoneNumber",user.getPhoneNumber())
.claim("headImgUrl",user.getHeadImgUrl())
.claim("uuid",user.getUuid())
.claim("id",user.getId())
.compact();
return jwt;
}
@Test
public void testNullClaim() throws Exception {
Settings settings = Settings.builder()
.put("signing_key", BaseEncoding.base64().encode(secretKey))
.put("roles_key", "roles")
.build();
String jwsToken = Jwts.builder()
.setSubject("Leonard McCoy")
.claim("roles", null)
.signWith(SignatureAlgorithm.HS512, secretKey).compact();
HTTPJwtAuthenticator jwtAuth = new HTTPJwtAuthenticator(settings, null);
Map<String, String> headers = new HashMap<String, String>();
headers.put("Authorization", jwsToken);
AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest(headers, new HashMap<String, String>()), null);
Assert.assertNotNull(creds);
Assert.assertEquals("Leonard McCoy", creds.getUsername());
Assert.assertEquals(0, creds.getBackendRoles().size());
}
@Test
public void testNonStringAlternativeSubject() throws Exception {
Settings settings = Settings.builder()
.put("signing_key", BaseEncoding.base64().encode(secretKey))
.put("subject_key", "asub")
.build();
String jwsToken = Jwts.builder()
.setSubject("Leonard McCoy")
.claim("roles", "role1,role2")
.claim("asub", false)
.signWith(SignatureAlgorithm.HS512, secretKey).compact();
HTTPJwtAuthenticator jwtAuth = new HTTPJwtAuthenticator(settings, null);
Map<String, String> headers = new HashMap<String, String>();
headers.put("Authorization", jwsToken);
AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest(headers, new HashMap<String, String>()), null);
Assert.assertNotNull(creds);
Assert.assertEquals("false", creds.getUsername());
Assert.assertEquals(0, creds.getBackendRoles().size());
}
@JsonView(Views.Public.class)
@RequestMapping(value = "/login", method = RequestMethod.POST)
public ResponseEntity<?> login(@RequestBody LoginModel data) {
User user = userService.getByUsername(data.getUsername());
if (user == null) {
return new ResponseEntity(new LoginResponseBody(false, null, "User with that name isn't exist"),
HttpStatus.OK);
}
if (!Objects.equals(user.getPassword(), MD5.getHash(data.getPassword()))) {
return new ResponseEntity(new LoginResponseBody(false, null, "wrong_password"),
HttpStatus.OK);
}
String token = Jwts.builder()
.setSubject(data.getUsername())
.signWith(SignatureAlgorithm.HS512, key)
.compact();
return new ResponseEntity(new LoginResponseBody(true, token), HttpStatus.OK);
}
/**
* 创建jwt
* @param id
* @param subject
* @param ttlMillis
* @return
* @throws Exception
*/
public String createJWT(String id, String subject, long ttlMillis) throws Exception {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS512;
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
SecretKey key = generalKey();
JwtBuilder builder = Jwts.builder()
.setId(id)
.setIssuedAt(now)
.setSubject(subject)
.signWith(signatureAlgorithm, key);
if (ttlMillis >= 0) {
long expMillis = nowMillis + ttlMillis;
Date exp = new Date(expMillis);
builder.setExpiration(exp);
}
return builder.compact();
}
/** Create an ES-based JWT for the given project id, signed with the given private key. */
private static String createJwtEs(String projectId, String privateKeyFile) throws Exception {
DateTime now = new DateTime();
// Create a JWT to authenticate this device. The device will be disconnected after the token
// expires, and will have to reconnect with a new token. The audience field should always be set
// to the GCP project id.
JwtBuilder jwtBuilder =
Jwts.builder()
.setIssuedAt(now.toDate())
.setExpiration(now.plusMinutes(20).toDate())
.setAudience(projectId);
byte[] keyBytes = Files.readAllBytes(Paths.get(privateKeyFile));
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("EC");
return jwtBuilder.signWith(SignatureAlgorithm.ES256, kf.generatePrivate(spec)).compact();
}
@Test
void testFilterNotSecureSecCtx() {
final Key key = secretKeyFor(SignatureAlgorithm.HS512);
final String token = Jwts.builder().setSubject(WEBID1).signWith(key).compact();
final ContainerRequestContext mockCtx = mock(ContainerRequestContext.class);
when(mockCtx.getSecurityContext()).thenReturn(mockSecurityContext);
when(mockSecurityContext.isSecure()).thenReturn(true);
when(mockCtx.getHeaderString(AUTHORIZATION)).thenReturn("Bearer " + token);
final OAuthFilter filter = new OAuthFilter();
filter.setAuthenticator(new JwtAuthenticator(key));
filter.filter(mockCtx);
verify(mockCtx).setSecurityContext(securityArgument.capture());
assertEquals(WEBID1, securityArgument.getValue().getUserPrincipal().getName(), "Unexpected agent IRI!");
assertEquals(OAuthFilter.SCHEME, securityArgument.getValue().getAuthenticationScheme(), "Unexpected scheme!");
assertTrue(securityArgument.getValue().isSecure(), "Unexpected secure flag!");
assertFalse(securityArgument.getValue().isUserInRole("some role"), "Unexpectedly in user role!");
}
/**
* Test that .authenticate does not throw an error when provided with
* a valid JWT token.
*/
@Test
public void testAuthenticateDoesNotThrowWHenProvidedWithAValidJWTToken() throws AuthenticationException {
final Key secretKey = createSecretKey();
final SignatureAlgorithm signatureAlgorithm = getValidSignatureAlgorithm();
final Principal principal = generatePrincipal();
final String jwt = createJwtToken(signatureAlgorithm, secretKey, principal);
final JsonWebTokenAuthenticator authenticator = createAuthenticator(secretKey, signatureAlgorithm);
// Shouldn't throw, because we created a valid jwt token
// using the same secret key as the authenticator.
authenticator.authenticate(jwt);
}
@Override
public String getToken(final String username, final String password) {
if (username == null || password == null) {
return null;
}
final User user = (User) userDetailsService.loadUserByUsername(username);
Map<String, Object> tokenData = new HashMap<>();
if (password.equals(user.getPassword())) {
tokenData.put("clientType", "user");
tokenData.put("userID", user.getId());
tokenData.put("username", user.getUsername());
tokenData.put("token_create_date", LocalDateTime.now());
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, tokenExpirationTime);
tokenData.put("token_expiration_date", calendar.getTime());
JwtBuilder jwtBuilder = Jwts.builder();
jwtBuilder.setExpiration(calendar.getTime());
jwtBuilder.setClaims(tokenData);
return jwtBuilder.signWith(SignatureAlgorithm.HS512, tokenKey).compact();
} else {
throw new ServiceException("Authentication error", this.getClass().getName());
}
}
/**
* description 登录签发 JWT ,这里已经在 passwordFilter 进行了登录认证
*
* @param request 1
* @param response 2
* @return com.usthe.bootshiro.domain.vo.Message
*/
@ApiOperation(value = "用户登录", notes = "POST用户登录签发JWT")
@PostMapping("/login")
public Message accountLogin(HttpServletRequest request, HttpServletResponse response) {
Map<String, String> params = RequestResponseUtil.getRequestBodyMap(request);
String appId = params.get("appId");
// 根据appId获取其对应所拥有的角色(这里设计为角色对应资源,没有权限对应资源)
String roles = accountService.loadAccountRole(appId);
// 时间以秒计算,token有效刷新时间是token有效过期时间的2倍
long refreshPeriodTime = 36000L;
String jwt = JsonWebTokenUtil.issueJWT(UUID.randomUUID().toString(), appId,
"token-server", refreshPeriodTime >> 1, roles, null, SignatureAlgorithm.HS512);
// 将签发的JWT存储到Redis: {JWT-SESSION-{appID} , jwt}
redisTemplate.opsForValue().set("JWT-SESSION-" + appId, jwt, refreshPeriodTime, TimeUnit.SECONDS);
AuthUser authUser = userService.getUserByAppId(appId);
authUser.setPassword(null);
authUser.setSalt(null);
LogExeManager.getInstance().executeLogTask(LogTaskFactory.loginLog(appId, IpUtil.getIpFromRequest(WebUtils.toHttp(request)), (short) 1, "登录成功"));
return new Message().ok(1003, "issue jwt success").addData("jwt", jwt).addData("user", authUser);
}
/**
* Issue a JWT token
*
* @param authenticationTokenDetails
* @return
*/
public String issueToken(AuthenticationTokenDetails authenticationTokenDetails) {
return Jwts.builder()
.setId(authenticationTokenDetails.getId())
.setIssuer(settings.getIssuer())
.setAudience(settings.getAudience())
.setSubject(authenticationTokenDetails.getUsername())
.setIssuedAt(Date.from(authenticationTokenDetails.getIssuedDate().toInstant()))
.setExpiration(Date.from(authenticationTokenDetails.getExpirationDate().toInstant()))
.claim(settings.getAuthoritiesClaimName(), authenticationTokenDetails.getAuthorities())
.claim(settings.getRefreshCountClaimName(), authenticationTokenDetails.getRefreshCount())
.claim(settings.getRefreshLimitClaimName(), authenticationTokenDetails.getRefreshLimit())
.signWith(SignatureAlgorithm.HS256, settings.getSecret())
.compact();
}
/**
* Gets an refresh token JWT for testing that is always the same.
*/
public static String getTestRefreshToken() {
if (TEST_REFRESH_TOKEN != null) {
return TEST_REFRESH_TOKEN;
}
final Map<String, Object> claims = new HashMap<>();
claims.put("typ", "refresh");
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(Date.from(Instant.now().minus(Duration.ofHours(1))))
.setSubject("uniqueUserID")
.setExpiration(new Date(((Calendar.getInstance().getTimeInMillis() + (5 * 60 * 1000)))))
.setClaims(claims)
.signWith(
SignatureAlgorithm.HS256,
"abcdefghijklmnopqrstuvwxyz1234567890".getBytes(StandardCharsets.UTF_8))
.compact();
}
/**
* <p>
* 验证签名并解析
* </p>
*/
public static JwtParser verifyParser() {
try {
SSOConfig config = SSOConfig.getInstance();
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.forName(config.getSignAlgorithm());
if (SSOConstants.RSA.equals(signatureAlgorithm.getFamilyName())) {
if(null == RSA_PUBLICKEY) {
ClassPathResource resource = new ClassPathResource(config.getRsaCertStore());
RSA_PUBLICKEY = RsaKeyHelper.getRsaPublicKey(resource.getInputStream());
}
// RSA 签名验证
return Jwts.parserBuilder().setSigningKey(RSA_PUBLICKEY).build();
}
// 普通签名验证
SecretKey secretKey = getSecretKey(config.getSignKey(), signatureAlgorithm);
return Jwts.parserBuilder().setSigningKey(secretKey).build();
} catch (Exception e) {
throw new KissoException("verifyParser error.", e);
}
}
@Override
public SignatureValidator createSignatureValidator(SignatureAlgorithm alg, Key key) {
Assert.notNull(alg, "SignatureAlgorithm cannot be null.");
Assert.notNull(key, "Signing Key cannot be null.");
switch (alg) {
case HS256:
case HS384:
case HS512:
return new MacValidator(alg, key);
case RS256:
case RS384:
case RS512:
case PS256:
case PS384:
case PS512:
return new RsaSignatureValidator(alg, key);
case ES256:
case ES384:
case ES512:
return new EllipticCurveSignatureValidator(alg, key);
default:
throw new IllegalArgumentException("The '" + alg.name() + "' algorithm cannot be used for signing.");
}
}
@Test
public void testClientCanAuthenticateWithAJwt() {
final JsonWebTokenConfig jwtConfigInFixture =
(JsonWebTokenConfig)RULE.getConfiguration().getAuthenticationConfiguration();
final String secretKeyBase64 = jwtConfigInFixture.getSecretKey();
final byte[] secretKeyData = Base64.getDecoder().decode(secretKeyBase64);
final SignatureAlgorithm alg = jwtConfigInFixture.getSignatureAlgorithm();
final Key secretKey = new SecretKeySpec(secretKeyData, 0, secretKeyData.length, alg.toString());
final String username = TestHelpers.generateRandomString();
final Principal userPrincipal = new PrincipalImpl(username);
final String jwt = JsonWebTokenAuthenticator.createJwtToken(alg, secretKey, userPrincipal);
final Invocation.Builder b = generateRequest(RULE, HTTP_USERS_PATH + "/current");
b.header("Authorization", "Bearer " + jwt);
final Response response = b.get();
assertThat(response.getStatus()).isEqualTo(OK);
final APIUserDetails parsedResponse = response.readEntity(APIUserDetails.class);
assertThat(parsedResponse.getId().toString()).isEqualTo(username);
}
public static String createToken(String username, String role, boolean isRememberMe) {
long expiration = isRememberMe ? EXPIRATION_REMEMBER : EXPIRATION;
HashMap<String, Object> map = new HashMap<>();
map.put(ROLE_CLAIMS, 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();
}
public static String createToken(String username, String role, boolean isRememberMe) {
long expiration = isRememberMe ? EXPIRATION_REMEMBER : EXPIRATION;
HashMap<String, Object> map = new HashMap<>();
map.put(ROLE_CLAIMS, 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();
}
private String createTokenWithDifferentSignature() {
Key otherKey = Keys.hmacShaKeyFor(Decoders.BASE64
.decode("Xfd54a45s65fds737b9aafcb3412e07ed99b267f33413274720ddbb7f6c5e64e9f14075f2d7ed041592f0b7657baf8"));
return Jwts.builder()
.setSubject("anonymous")
.signWith(otherKey, SignatureAlgorithm.HS512)
.setExpiration(new Date(new Date().getTime() + ONE_MINUTE))
.compact();
}
private String doGenerateToken(Map<String, Object> claims, String subject, String audience) {
final Date createdDate = clock.now();
final Date expirationDate = calculateExpirationDate(createdDate);
System.out.println("doGenerateToken " + createdDate);
return Jwts.builder()
.setClaims(claims)
.setSubject(subject)
.setAudience(audience)
.setIssuedAt(createdDate)
.setExpiration(expirationDate)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
@Test
void testAuthenticateSubNoWebIss() {
final Key key = secretKeyFor(SignatureAlgorithm.HS512);
final String token = Jwts.builder().setSubject("acoburn").setIssuer("some org").signWith(key).compact();
final Authenticator authenticator = new JwtAuthenticator(key);
final Principal p = authenticator.authenticate(token);
assertNull(p, "Unexpected principal!");
}
@Test
void testAuthenticate() {
final Key key = secretKeyFor(SignatureAlgorithm.HS256);
final String token = Jwts.builder().setSubject("https://people.apache.org/~acoburn/#i")
.signWith(key).compact();
final Authenticator authenticator = new JwtAuthenticator(key);
final Principal p = authenticator.authenticate(token);
assertNotNull(p, "Missing principal!");
assertEquals("https://people.apache.org/~acoburn/#i", p.getName(), "Incorrect webid!");
}
@Override
protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse rsp, FilterChain chain,
Authentication auth) throws IOException, ServletException {
Instant now = Instant.now();
String token = Jwts.builder().setSubject(auth.getName())
.claim("authorities",
auth.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()))
.setIssuedAt(Date.from(now)).setExpiration(Date.from(now.plusSeconds(config.getExpiration())))
.signWith(SignatureAlgorithm.HS256, config.getSecret().getBytes()).compact();
rsp.addHeader(config.getHeader(), config.getPrefix() + " " + token);
}
private static Map<SignatureAlgorithm, String> createEcCurveNames() {
Map<SignatureAlgorithm, String> m = new HashMap<SignatureAlgorithm, String>(); //alg to ASN1 OID name
m.put(SignatureAlgorithm.ES256, "secp256r1");
m.put(SignatureAlgorithm.ES384, "secp384r1");
m.put(SignatureAlgorithm.ES512, "secp521r1");
return m;
}
String generateToken(Map<String, Object> claims) {
return Jwts.builder()
.setClaims(claims)
.setExpiration(generateExpirationDate())
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
public MacSigner(SignatureAlgorithm alg, Key key) {
super(alg, key);
Assert.isTrue(alg.isHmac(), "The MacSigner only supports HMAC signature algorithms.");
if (!(key instanceof SecretKey)) {
String msg = "MAC signatures must be computed and verified using a SecretKey. The specified key of " +
"type " + key.getClass().getName() + " is not a SecretKey.";
throw new IllegalArgumentException(msg);
}
}
@Test
public void testFour() throws NoSuchAlgorithmException, NoSuchProviderException {
String nonce = UUID.randomUUID().toString();
String client_id = "12345";
String subject = "Bob";
String locale = Locale.getDefault().getLanguage().replace('_', '-');
Matcher m = uuid_pattern.matcher(nonce);
boolean good = m.find();
if (!good) {
System.out.println("Bad UUID:\n" + nonce);
}
assertTrue(good);
Date now = new Date();
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
String jws = Jwts.builder()
.setIssuer(LTI_13_ISSUER)
.setSubject(subject)
.setAudience(client_id)
.setIssuedAt(now)
.setExpiration(new Date(now.getTime() + 600000L)) // Milliseconds
.claim(LTI13ConstantsUtil.KEY_NONCE, nonce)
.claim(LTI13ConstantsUtil.KEY_LOCALE, locale)
.signWith(key)
.compact();
String body = getBody(jws, key);
good = body.contains(LTI_13_ISSUER);
if (!good) {
System.out.println("Bad body: " + body);
}
assertTrue(good);
}
public Map<String, String> refreshSecrets() {
SecretKey key = MacProvider.generateKey(SignatureAlgorithm.HS256);
secrets.put(SignatureAlgorithm.HS256.getValue(), TextCodec.BASE64.encode(key.getEncoded()));
key = MacProvider.generateKey(SignatureAlgorithm.HS384);
secrets.put(SignatureAlgorithm.HS384.getValue(), TextCodec.BASE64.encode(key.getEncoded()));
key = MacProvider.generateKey(SignatureAlgorithm.HS512);
secrets.put(SignatureAlgorithm.HS512.getValue(), TextCodec.BASE64.encode(key.getEncoded()));
return secrets;
}
@Test
public void testJwtAuthenticator()
throws Exception
{
try (TestingPrestoServer server = TestingPrestoServer.builder()
.setProperties(ImmutableMap.<String, String>builder()
.putAll(SECURE_PROPERTIES)
.put("http-server.authentication.type", "jwt")
.put("http-server.authentication.jwt.key-file", HMAC_KEY)
.build())
.build()) {
HttpServerInfo httpServerInfo = server.getInstance(Key.get(HttpServerInfo.class));
String nodeId = server.getInstance(Key.get(NodeInfo.class)).getNodeId();
testLogIn(httpServerInfo.getHttpUri(), false);
testNeverAuthorized(httpServerInfo.getHttpsUri(), client);
String hmac = Files.readString(Paths.get(HMAC_KEY));
String token = Jwts.builder()
.signWith(SignatureAlgorithm.HS256, hmac)
.setSubject("test-user")
.setExpiration(Date.from(ZonedDateTime.now().plusMinutes(5).toInstant()))
.compact();
OkHttpClient clientWithJwt = client.newBuilder()
.authenticator((route, response) -> response.request().newBuilder()
.header(AUTHORIZATION, "Bearer " + token)
.build())
.build();
testAlwaysAuthorized(httpServerInfo.getHttpsUri(), clientWithJwt, nodeId);
}
}