我正在尝试获取UserDetails
对象,如下所示。但是,我遇到一些困难并且无法获得UserDetails
对象,因此JSONObject
中只有authentication.getAttributes()
。在micronaut中,还有其他方法可以获取UserDetails
对象吗?
自定义UserDetails
对象:
public class MyUserPrincipal implements UserDetails {
private Account account;
public MyUserPrincipal(Account account) {
this.account = account;
}
public Account getAccount() {
return getAccount();
}
}
Rest API:
//micronaut
@Post(value = "/echo")
@Status(HttpStatus.OK)
public Long echo(@Nullable Authentication authentication) {
Long accountId = (Long)((JSONObject)authentication.getAttributes().get("account")).get("id");
return accountId;
}
例如,在Spring Security中,在参数中使用@AuthenticationPrincipal
注释很容易。
Rest API:
@GET
public ResponseEntity<?> echo(@AuthenticationPrincipal MyUserPrincipal user) {
return new ResponseEntity<>(user.getAccount().getAccountId(), HttpStatus.OK);
}
答案 0 :(得分:3)
如果您仍在寻找解决方案,这是可行的。
您必须提供JwtAuthenticationFactory
的实现并替换默认的DefaultJwtAuthenticationFactory
。
类似这样的东西(下面的代码在Kotlin中):
@Singleton
@Replaces(bean = DefaultJwtAuthenticationFactory::class)
class CustomJwtAuthenticationFactory() : JwtAuthenticationFactory {
override fun createAuthentication(token: JWT?): Optional<Authentication> {
try {
val builder = JWTClaimsSet.Builder()
builder.claim("username", token?.jwtClaimsSet?.getStringClaim("username"))
return Optional.of(AuthenticationJWTClaimsSetAdapter(jwtClaims))
} catch (e: Exception) {
throw RuntimeException("ParseException creating authentication", e)
}
}
}
使用构建器添加的所有声明都将添加到Authentication
对象中,并且可以在任何控制器中访问,例如:
@Get("/hello-world")
fun hello(authentication: Authentication): String =
authentication["username"] as String
如果您使用的是Kotlin,则还可以在Authentication方法上添加扩展方法,以获取添加到Authentication类的属性,例如:
fun Authentication.username(): String = this.attributes["username"]
注意:username
仅是示例。可以作为Authentication实例上的name
实例变量。
答案 1 :(得分:0)
UserDetails不存在。唯一可用的对象是身份验证。如果要标准化上面的代码,可以创建一个处理该特定属性注入的Bean。
您可以通过创建注释以及AnnotatedRequestArgumentBinder
的实现来使用注释来指定注入。类似于以下内容:
public class Temp implements AnnotatedRequestArgumentBinder<YourAnnotation, Long> {
@Override
public Class<YourAnnotation> getAnnotationType() {
return YourAnnotation.class;
}
@Override
public BindingResult<Long> bind(ArgumentConversionContext<Long> context, HttpRequest<?> source) {
if (source.getAttributes().contains(OncePerRequestHttpServerFilter.getKey(SecurityFilter.class))) {
final Optional<Authentication> authentication = source.getUserPrincipal(Authentication.class);
if (authentication.isPresent()) {
return () -> (Long)((JSONObject)authentication.getAttributes().get("account")).get("id");
}
}
return ArgumentBinder.BindingResult.EMPTY;
}
}