我想使用Spring security的PreAuthorize注释来保护我的REST API,在这里我定义了被授权访问方法的角色:
@Transactional
@POST
@PreAuthorize("hasRole('ROLE_ADMIN')")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response create(User user) throws BusinessException {
LOG.info("POST Request: Creation of a new user with username [{}]", user.getUsername());
UserValidator.validateUser(user);
User createdUser = userDao.create(user);
return Response.ok(createdUser).build();
}
当我使用角色为“role_admin”的用户的有效承载令牌调用API方法时,我会得到以下异常:
09-Sep-2014 16:13:40.977 SEVERE [http-nio-8080-exec-6] com.sun.jersey.spi.container.ContainerResponse.mapMappableContainerException The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AbstractAccessDecisionManager.checkAllowIfAllAbstainDecisions(AbstractAccessDecisionManager.java:70)
at org.springframework.security.access.vote.UnanimousBased.decide(UnanimousBased.java:107)
at ...
{
"error": "unauthorized",
"error_description": "Full authentication is required to access this resource"
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/security/oauth2
http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd">
<context:property-placeholder location="classpath:main.properties"/>
<sec:global-method-security pre-post-annotations="enabled" />
<oauth:expression-handler id="oauthExpressionHandler" />
<!-- Definition of the Authentication Service -->
<sec:http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager">
<sec:intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY"/>
<sec:anonymous enabled="false"/>
<sec:http-basic entry-point-ref="clientAuthenticationEntryPoint"/>
<!-- include this only if you need to authenticate clients via request parameters -->
<sec:custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER"/>
<sec:access-denied-handler ref="oauthAccessDeniedHandler"/>
</sec:http>
<!-- Protected resources -->
<sec:http auto-config="true"
entry-point-ref="oauthAuthenticationEntryPoint"/>
<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="dstest" />
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="dstest/client"/>
<property name="typeName" value="Basic"/>
</bean>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler"/>
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager"/>
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased">
<constructor-arg>
<list>
<bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter"/>
<bean class="org.springframework.security.access.vote.RoleVoter"/>
<bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
</list>
</constructor-arg>
</bean>
<!-- Authentication in config file -->
<sec:authentication-manager id="clientAuthenticationManager">
<sec:authentication-provider user-service-ref="clientDetailsUserService"/>
</sec:authentication-manager>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider>
<sec:jdbc-user-service data-source-ref="securityDataSource"/>
</sec:authentication-provider>
</sec:authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails"/>
</bean>
<!-- Token Store -->
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore">
<constructor-arg ref="securityDataSource" />
</bean>
<bean id="oAuth2RequestFactory" class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
<constructor-arg ref="clientDetails"/>
</bean>
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore"/>
<property name="supportRefreshToken" value="true"/>
<property name="clientDetailsService" ref="clientDetails"/>
<!-- VIV -->
<property name="accessTokenValiditySeconds" value="10"/>
</bean>
<bean id="userApprovalHandler"
class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler">
<property name="tokenStore" ref="tokenStore"/>
<property name="requestFactory" ref="oAuth2RequestFactory"/>
</bean>
<!-- Token management -->
<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices"
user-approval-handler-ref="userApprovalHandler" token-endpoint-url="/oauth/token">
<oauth:authorization-code/>
<oauth:implicit/>
<oauth:refresh-token/>
<oauth:client-credentials/>
<oauth:password/>
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter"
resource-id="dstest"
token-services-ref="tokenServices"/>
<!-- Client Definition -->
<oauth:client-details-service id="clientDetails">
<oauth:client client-id="healthdata-client"
authorized-grant-types="password,authorization_code,refresh_token,implicit,redirect"
authorities="ROLE_CLIENT, ROLE_TRUSTED_CLIENT"
redirect-uri="/web"
scope="read,write,trust"
access-token-validity="300"
refresh-token-validity="6000"/>
</oauth:client-details-service>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<display-name>Spring MVC Application BASIC AUTH</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml
/WEB-INF/rest-dispatcher-servlet.xml
/WEB-INF/security.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>rest-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest-dispatcher</servlet-name>
<url-pattern>/oauth/token</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Spring servlets</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>be.spring.security.api</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>be.spring;org.codehaus.jackson.jaxrs</param-value>
</init-param>
<!-- optional: JSON support apart from jaxb -->
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Spring servlets</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
我找到了解决我问题的办法。Web安全服务是使用该元素配置的,我必须将受保护的资源定义从:
<sec:http auto-config="true"
entry-point-ref="oauthAuthenticationEntryPoint"/>
致:
<sec:http auto-config="true">
<sec:custom-filter ref="resourceServerFilter"
before="PRE_AUTH_FILTER"/>
<sec:access-denied-handler
ref="oauthAccessDeniedHandler"/>
</sec:http>
必须引用resourceServerFilter,才能由安全机制拾取,并且必须将before属性设置为“pre_auth_filter”。
我正在使用osgi和基于spring注释的配置。(使用virgo部署应用程序) @preauthorize方法impl上的注释不起作用。 尽管用户没有该角色,但它仍允许用户访问它。 如果我在接口上放置相同的注释,它会为所有用户抛出AccessDenied异常。例外情况: 这是我的配置: 我使用的是spring-security 3.0.4.Release
我正在开发一个spring rest项目,并使用OAuth2.0来保护这些API免受未经授权的访问。 前端:Angular.js后端:Spring Rest+Spring Security+Oauth2 2)我从后端获得了一个令牌,并使用该令牌来访问API。 现在我的问题是,一旦我用/oauth/token点击后端?grant_type=password&client_id=angularapp&
我正在开发配置了SSO/OAuth2安全性的Spring Boot应用程序。身份验证对我的rest控制器很有效,现在我需要用restendpoint保护我的Apache Camel路由。 据我所知,有几种方法可以做到这一点: 通过将身份验证处理器添加到我的路线 通过向我的路线添加策略(SpringSecurityAuthorizationPolicy) jettyendpoint的“按处理程序”选
我们正在构建一个REST资源服务器(一个Java示例应用程序),我们计划使用MITREID Connect项目提供的RFC7662定义的标识传播机制来保护它。我们测试了两种配置方法,XML设置,以及添加到resource server类中的基于注释的设置(参见下面附上的示例代码)。 我们的测试显示了Spring Security例程的成功初始化,但是我们没有成功地触发通过授权头的承载令牌通过。请求
问题内容: 我成功配置了spring-security- oauth2,以便外部应用程序可以通过我的应用程序进行身份验证。但是,基于外部应用程序以及基于用户允许的内容,客户端只能访问我的API的子集。可用子集由OAuth范围确定。 在经典的Spring应用程序中,我可以使用@PreAuthorize来基于角色强制执行边界: 在使用OAuth并结合作用域而不是角色时,我该怎么做? 问题答案: Spr
我创建了一个包含一些基本crud方法的CrudController。这很好用。当我想保护这个控制器时,我可以重写超类中的方法,这很好。然而,我不想仅仅为了安全而重写每个方法。为此,我想在类上使用@Secured或@PreAuthorize。 我使用的是Spring Boot 2.2.2(最新版本)。 示例Crud基类 实现类 预期行为 当一个类被注释为@PreAuthorize或@安全时,我希望所