我正与春布特和React合作,认证和授权用户,然后进入安全终点。
The API creates a token when a login request is made and then decodes it:
package com.example.demo.service;
import java.security.Key;
import java.util.Date;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import jakarta.xml.bind.DatatypeConverter;
@Service
public class JwTTokenProviderService {
@Value("${jwt.secret}")
private String JWT_SECRET_KEY;
// the JWT_SECRET_KEY is populated in the application.properties file.
public String generateToken(String username, String role) {
//The JWT signature algorithm we will be using to sign the token
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
Key signingKey = new SecretKeySpec(DatatypeConverter.parseBase64Binary(JWT_SECRET_KEY), signatureAlgorithm.getJcaName());
long jwtExpirationInMs = 36000;
System.out.println("Username at generating token is " + username);
System.out.println("Role at generating token is " + role);
return Jwts.builder()
.setSubject(username)
.claim("hasRole", role)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + jwtExpirationInMs))
.signWith(signingKey, signatureAlgorithm)
.compact();
}
public String getAllClaimsFromToken(String token) {
System.out.println("Token at getAllClaimsFromToken is " + token);
try {
byte[] arrSecret = DatatypeConverter.parseBase64Binary(JWT_SECRET_KEY);
Key signingKey = new SecretKeySpec(arrSecret, SignatureAlgorithm.HS256.getJcaName());
Jws<Claims> jwsClaims = Jwts.parser()
.setSigningKey(signingKey)
.parseClaimsJws(token);
Claims claims = jwsClaims.getBody();
return claims.get("hasRole", String.class); //
} catch (Exception e) {
System.out.println("Could not get all claims TOken from passed token");
System.out.println("Exception is " + e);
return null;
}
}
}
这是发出请求的方法:
getInfoForUser(username) {
try {
console.log("Username at Axios is, ", username)
console.log("User token at getInfoForUser is: ", localStorage.getItem( userToken ))
return axios.post("http://myserver:8080/myapp/login/get-info-for-user", {params: {
username: username
},
headers: {
Content-Type : application/json; charset=UTF-8 ,
Authorization : ......Bearer ${localStorage.getItem("userToken")}......,
Accept : application/json
}}
)
} catch (error) {
console.log("Error is, ", error)
}
}
这是控制器的附担保方法:
@PreAuthorize("hasRole( ROLE_USER )")
@PostMapping("/get-info-for-user")
public Object[] getInfoForUser(@Param("username") String username) {
return userService.getInfoForUser(username);
}
之后,这又产生了一个回头角,但是,这预示着问题,因为它在实施象征性机制之前运作。
The JwtResponse file, or model for the authorization header:
package com.example.demo.model;
import java.util.List;
public class JwtResponse {
private String token;
private String type = "Bearer";
private String username;
private String hasRole;
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String gethasRole() {
return hasRole;
}
public void sethasRole(String hasRole) {
this.hasRole = hasRole;
}
public JwtResponse(String token, String username, String hasRole) {
super();
this.token = token;
this.username = username;
this.hasRole = hasRole;
}
}
5. 安保考虑使说明能够:
@Configuration(proxyBeanMethods = false)
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig {
//...
}
参考需要:
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
This is the feedback once the user logs in:
用户名称、作用、标注和类型“Bearer”都是通过的,然后在附担保的终端点要求中作为授权负责人提交这一信息。
在我从申请中输入秘密后,还核实了该标的。 财产档案:
It is the first time I am attempting to do this and generally speaking, checked over these things:
- Used a POST method and not GET in the frontend and @PostMapping for the backend; I ve tried switching but the result is the same.
- The JWT secret is secured in the application.properties file.
- I do get a warning that the parser() and setSigningKey() method from it are deprecated in the version of JJWT I am using, but I haven t been able to locate a good example - though that should not necessarily trigger the 401 error.
- Because I am using the @PreAuthorize annotation, which looks for ROLE_ as a prefix, I ve done that in the database, so it returns the same syntax.
- I thought about the "hasRole" attribute in the annotation and made it the same in the JwtResponse model, which builds the authorization header.
- I thought it was an issue with the secret being generated, as the token returned an invalid signature, but that got corrected when I put in the secret into the checker.
- Everything is encoded and secured and there are no plain text values as relevant to the token being passed around. Or rather, should there be nothing but the token in the authorization header of the request?
- Pre/Post is enabled in the security configuration.
这或许是我所看到的关于SO的最有益的指南:
任何见解都将受到赞赏......
......