什么是Micronaut的@AuthenticationPrincipal替代方案?

时间:2019-02-12 17:16:03

标签: java authentication micronaut

我正在尝试获取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);
}

2 个答案:

答案 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;
    }
}