使用Spring

时间:2017-01-13 12:08:57

标签: spring spring-mvc authentication jersey

我正在尝试创建自定义“userContext”作为具有请求范围的SpringBean,但我无法这样做。基本上我有一个Jersey REST api,我想使用自定义过滤器进行身份验证和授权,我在其中自动装配我的“userContext”bean。这个过程如下:

  1. 调用REST API(我希望Spring创建userContext bean的新实例)
  2. AuthenticationFilter自动装配userBean的新实例并填充它
  3. AuthorizationFilter自动装配现在填充的同一个实例并授权用户
  4. 当我第一次调用REST api(服务器重启后)时,它按预期工作,但任何其他调用都失败,因为AutorizationFilter获取了userBean的空实例。我希望对我的范围有一些根本性的误解。

    顺便说一句:我想避免直接使用ThreadLocal,因为请求范围应该处理它

    我想知道,为什么authorizationFilter没有看到userBean的填充版本以及第一次调用的原因。提前感谢您的帮助。

    代码的某些部分:

    @Secured({Role.ADMIN}) //custom annotation
    @GET
    @Path("{id}")
    public Response getUserById(@PathParam("id") Long id) throws IOException, MainException {
    
    @Secured //custom annotation
    @Provider
    @Priority(Priorities.AUTHENTICATION)
    @Scope(value="request", proxyMode= ScopedProxyMode.TARGET_CLASS)
    public class AuthenticationFilter implements ContainerRequestFilter 
        @Autowired
        private User userContext;
    
    
    @Secured //custom annotation
    @Provider
    @Priority(Priorities.AUTHORIZATION)
    @Scope(value="request", proxyMode= ScopedProxyMode.TARGET_CLASS)
    public class AuthorizationFilter implements ContainerRequestFilter {
        @Autowired
        private User userContext;
    
    
    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    @Component
    @Scope(value = "request",  proxyMode = ScopedProxyMode.TARGET_CLASS)
    public class User extends ModelBase implements Serializable {
    

1 个答案:

答案 0 :(得分:0)

由于Providers不是请求作用域,我必须注入整个ApplicationContext,这样我就可以直接修改userContext bean的正确实例(这是请求作用域)。基本上我在两个过滤器中做了类似的事情:

@Autowired
private ApplicationContext applicationContext;

@Override
public void filter(ContainerRequestContext requestContext) throws IOException {

    User userBean=applicationContext.getBean(User.class);
    ....
    userBean.setSomething("aaa");

然后我可以在我的REST资源中自动装配这样的bean,因为它们是由defaul确定的请求:

@Component
@Api(value="/users", description = "Endpoint for Users listing")
@Consumes({MediaType.APPLICATION_JSON, Constants.API_VERSIONS.V1_HEADER_XML, Constants.API_VERSIONS.V1_HEADER_JSON})
@Produces({MediaType.APPLICATION_JSON, Constants.API_VERSIONS.V1_HEADER_XML, Constants.API_VERSIONS.V1_HEADER_JSON})
@Path("/users")
public class UserResource {

    private static final Logger logger = LoggerFactory.getLogger(UserResource.class);

    @Autowired
    private User authenticatedUser;

此解决方案应该是可行的,并且可以抵抗线程竞争条件等。