我實現了一個ContainerRequestFilter
進行基於JWT認證意想不到類型:JAX-RS:自定義的SecurityContext有當注入資源的方法
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
AuthenticationResult authResult = ...
if (authResult.isSuccessful()) {
// Client successfully authenticated.
// Now update the security context to be the augmented security context that contains information read from the JWT.
requestContext.setSecurityContext(new JwtSecurityContect(...));
} else {
// Client provided no or an invalid authentication token.
// Deny request by sending a 401 response.
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
}
}
}
正如你所看到的,我更新請求SecurityContext
,設置如果驗證成功,它將成爲我自己的自定義實現(JwtSecurityContext
)的一個實例。此實現添加額外的身份驗證和授權數據,我希望稍後在我的後續過濾器和我的資源方法中訪問這些數據。
我也實施了AuthorizationFilter
,在AuthenticationFilter
後立即調用。在這裏,我可以訪問更新的JwtSecurityContext
就好了。
但是,我在嘗試將JwtSecurityContext
注入資源(方法)時遇到了問題。我目前使用澤西
,和I've read the following in its documentation:
的
SecurityContext
可以直接從ContainerRequestContext
經由getSecurityContext()
方法檢索。您也可以使用setSecurityContext(SecurityContext)
方法,在請求上下文中用 替換請求上下文中的默認SecurityContext
,替換爲 。如果您在ContainerRequestFilter
中設置了 定製SecurityContext
實例,則將使用此 安全上下文實例注入JAX-RS 資源類字段。通過這種方式,您可以實施自定義 認證過濾器,該認證過濾器可以將您自己的SecurityContext
設置爲 。爲確保您的自定義驗證 請求過濾器的早期執行,請使用來自Priorities
的 常量將過濾器優先級設置爲AUTHENTICATION。早期執行您的身份驗證 過濾器將確保所有其他過濾器,資源,資源方法 和子資源定位器將與您的定製SecurityContext
實例一起執行。
我嘗試了JwtSecurityContext
注入資源的方法,像這樣:
@Path("/somepath")
public class SomeResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<SomeItem> getItems(@Context SecurityContext securityContext) {
// securityContext is of type 'SecurityContextInjectee'
}
}
正如評論指出,該securityContext
變量的運行時類型變得SecurityContextInjectee
。從調試中,我發現這包裝了ContainerRequest
,後者又包裝了我的JwtSecurityContext
。但是,沒有getter,並且我不想使用反射來深入查看此對象層次結構,因此我不知道如何獲取我的JwtSecurityContext
。
我已經嘗試將@Context SecurityContext securityContext
更改爲@Context JwtSecurityContext jwtSecurityContext
,但是如果我這樣做,變量將變爲null
。我也嘗試過野外注射,但這種行爲方式相同。
我正走向一條錯誤的道路嗎?我應該在我的資源方法中訪問我的自定義SecurityContext
嗎?一種替代方案可能是將我的所有數據都包含在我的JwtSecurityContext
中從getUserPrincipal
返回的Principal
實現中。我想代理(SecurityContextInjectee
)會將呼叫轉移到其底層的JwtSecurityContext
,因此返回我的Principal
,但我不確定,最終我寧願使用我的JwtSecurityContext
,而不是將這些值包裝在Principal
實現中。
@peeskillet有趣的是,我不知道我可以注入ContainerRequestContext。我想我將能夠調用getSecurityContext並返回我的自定義安全上下文。 –
@peeskillet是的,注入ContainerRequestContext並在該實例上調用getSecurityContext確實會返回JwtSecurityContext。謝謝!如果你願意,你可以把它作爲答案發布,我會接受它。 –