Spring security 如何在spring security oauth2中设置异常处理程序

Spring security 如何在spring security oauth2中设置异常处理程序,spring-security,exception-handling,spring-security-oauth2,Spring Security,Exception Handling,Spring Security Oauth2,我已经在我的服务器中实现了spring security oauth2以进行身份验证。现在我必须实现一个异常处理程序,当REST请求具有错误凭据、过期令牌、,它将以json字符串作为错误消息响应,而不是抛出异常。如何在spring security oauth2中设置异常处理程序。如果在配置文件中设置,它是否有默认的错误处理程序? 下面是我的代码 spring-security.xml: <?xml version="1.0" encoding="UTF-8" ?&

我已经在我的服务器中实现了spring security oauth2以进行身份验证。现在我必须实现一个异常处理程序,当REST请求具有错误凭据、过期令牌、,它将以json字符串作为错误消息响应,而不是抛出异常。如何在spring security oauth2中设置异常处理程序。如果在配置文件中设置,它是否有默认的错误处理程序? 下面是我的代码

spring-security.xml:

            <?xml version="1.0" encoding="UTF-8" ?>
        <beans xmlns="http://www.springframework.org/schema/beans"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
              xmlns:context="http://www.springframework.org/schema/context"
              xmlns:sec="http://www.springframework.org/schema/security" xmlns:mvc="http://www.springframework.org/schema/mvc"
              xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd
                    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
                    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
                    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
                    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd ">


              <http pattern="/oauth/token" create-session="stateless"  authentication-manager-ref="authenticationManager"
                    xmlns="http://www.springframework.org/schema/security" > 

                    <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" method="POST" />
                    <anonymous enabled="false" />
                    <http-basic entry-point-ref="clientAuthenticationEntryPoint" />
                    <custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" /> 
                    <access-denied-handler ref="oauthAccessDeniedHandler" />
              </http>

              <http pattern="/protected/**" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint"
                    xmlns="http://www.springframework.org/schema/security">
                    <anonymous enabled="false" />
                    <intercept-url pattern="/protected/**" method="GET" access="ROLE_APP" />
                    <!-- <intercept-url pattern="/resources/**" access="IS_AUTHENTICATED_FULLY" /> -->
                    <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
                    <access-denied-handler ref="oauthAccessDeniedHandler" />
              </http>

              <http pattern="/logout" create-session="never" 
                    entry-point-ref="oauthAuthenticationEntryPoint"
                    xmlns="http://www.springframework.org/schema/security">
                    <anonymous enabled="false" />
                    <intercept-url pattern="/logout" method="GET" />
                    <sec:logout invalidate-session="true" logout-url="/logout" success-handler-ref="logoutSuccessHandler"   />
                    <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
                    <access-denied-handler ref="oauthAccessDeniedHandler" />
              </http>

              <bean id="logoutSuccessHandler" class="com.example.myproject.security.LogoutImpl" >
                    <property name="tokenstore" ref="tokenStore"></property>
              </bean>

              <bean id="oauthAuthenticationEntryPoint"
                    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
                    <property name="exceptionTranslator" ref="myExceptionTranslator"></property>
              </bean>

          <bean id="myExceptionTranslator"
                    class="org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator">
              </bean>

              <bean id="clientAuthenticationEntryPoint"
                    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
                    <property name="realmName" value="springsec/client" />
                    <property name="typeName" value="Basic" />
              </bean>

              <bean id="oauthAccessDeniedHandler"
                    class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler">
              </bean>

              <bean id="clientCredentialsTokenEndpointFilter"
                    class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
                    <property name="authenticationManager" ref="authenticationManager" />
              </bean>

              <authentication-manager alias="authenticationManager"
                    xmlns="http://www.springframework.org/schema/security">
                    <authentication-provider user-service-ref="clientDetailsUserService" />
              </authentication-manager>

              <bean id="clientDetailsUserService"
                    class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
                    <constructor-arg ref="clientDetails" />
              </bean>

              <bean id="clientDetails" class="com.example.myproject.service.ClientService"/>

              <authentication-manager id="userAuthenticationManager" 
                    xmlns="http://www.springframework.org/schema/security">
                    <authentication-provider  user-service-ref="userService">
                    </authentication-provider>
              </authentication-manager>

              <bean id="userService"
                    class="com.example.myproject.service.UserService">
              </bean>

              <oauth:authorization-server
                    client-details-service-ref="clientDetails" token-services-ref="tokenServices">
                    <oauth:authorization-code />
                    <oauth:implicit/>
                    <oauth:refresh-token/>
                    <oauth:client-credentials />
                    <oauth:password authentication-manager-ref="userAuthenticationManager"/>
              </oauth:authorization-server>

              <oauth:resource-server id="resourceServerFilter"
                    resource-id="springsec" token-services-ref="tokenServices" />

              <!-- <bean id="tokenStore"
                    class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" /> -->

              <bean id="tokenStore"
                  class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore" >
                    <property name="authenticationKeyGenerator">
                          <bean class="com.example.myproject.service.UniqueAuthenticationKeyGenerator" />
                    </property> 
             </bean>

              <bean id="tokenServices" 
                    class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
                    <property name="tokenStore" ref="tokenStore" />
                    <property name="supportRefreshToken" value="true" />
                    <property name="accessTokenValiditySeconds" value="300000"></property>
                    <property name="clientDetailsService" ref="clientDetails" />
                    <property name="tokenEnhancer"><bean class="com.example.myproject.service.CustomTokenEnhancer" /></property>
              </bean>

              <sec:global-method-security
                    pre-post-annotations="enabled" proxy-target-class="true">
                    <!--you could also wire in the expression handler up at the layer of the 
                          http filters. See https://jira.springsource.org/browse/SEC-1452 -->
                    <sec:expression-handler ref="oauthExpressionHandler" />
              </sec:global-method-security>

              <oauth:expression-handler id="oauthExpressionHandler" />
              <oauth:web-expression-handler id="oauthWebExpressionHandler" />

        </beans>
UserService.java:

            @Component
        public class ClientService implements ClientDetailsService {

            @Autowired
            private OauthRepository oauthRepository;

            @Override
            public ClientDetails loadClientByClientId(String s) throws ClientRegistrationException{
                BaseClientDetails clientDetails = oauthRepository.getByClientId(s);
                      return clientDetails;

            }
        }
            @Component
        public class UserService implements UserDetailsService {

            @Autowired
            private OauthRepository oauthRepository;

            @Override
            public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
              UserDetails user = oauthRepository.getByUsername(s);
                      return user;

            }
        }
OauthRepository.java:

            @Repository
        @Transactional
        public class OauthRepository {

              @Autowired
              private SessionFactory sessionFactory;

              @Autowired
              private InMemoryTokenStore tokenStore;

              private org.hibernate.Session getCurrentSession(){
                    return sessionFactory.getCurrentSession();
              }



            public UserDetails getByUsername(String username) {

                    MyUser user=new MyUser();
                    user.setUserName(username);
                    Query query=getCurrentSession().createQuery("FROM User WHERE userName=:usrName");
                    query.setParameter("usrName", username);
                    List<SiUser> getUser=query.list();

                    User act=getUser.get(0);
                    user.setPassword(act.getPassword());
                    user.setUserId(act.getUserId());
                    user.setAuthorities(getAuthorities(act.getUserId()));

                    return user;
            }

            public BaseClientDetails getByClientId(String clientId) {
              System.out.println(" *** OauthRepository.getByClientId "+clientId);

              Query query=getCurrentSession().createQuery("FROM OauthClientDetails WHERE clientId=:clientId");
                    query.setParameter("clientId", clientId);
                    List<OauthClientDetails> getClient=query.list();

                    OauthClientDetails oauthClient=getClient.get(0);
                    BaseClientDetails details = new BaseClientDetails();
                    details.setClientId(oauthClient.getClientId());
                    List<String> grantTypesList = Arrays.asList(oauthClient.getAuthorizedGrantTypes().split(","));
                    details.setAuthorizedGrantTypes(grantTypesList); 
                    details.setClientSecret(oauthClient.getClientSecret());

                return details;


            }

        /**
         * Retrieves a collection of {@link GrantedAuthority} based on a numerical role
         * @param role the numerical role
         * @return a collection of {@link GrantedAuthority
         */
        public Collection<GrantedAuthority> getAuthorities(Integer role) {
              List<GrantedAuthority> authList = getGrantedAuthorities(getRoles(role));
              return authList;
        }
        /**
         * Converts a numerical role to an equivalent list of roles
         * @param role the numerical role
         * @return list of roles as as a list of {@link String}
         */
        public List<String> getRoles(Integer role) {
              List<String> roles = new ArrayList<String>();

              Query query=getCurrentSession().createQuery("FROM UserRole WHERE userID=:userId");
              query.setParameter("userId", role);
              List<SiUserRole> getUser=query.list();

              UserRole actRole=getUser.get(0);
              roles.add(actRole.getRole());
              return roles;
        }
        /**
         * Wraps {@link String} roles to {@link SimpleGrantedAuthority} objects
         * @param roles {@link String} of roles
         * @return list of granted authorities
         */
        public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) {
              List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
              for (String role : roles) {
                    authorities.add(new GrantedAuthorityImpl(role));
              }
              return authorities;
        }


        }
@存储库
@交易的
公共类OauthRepository{
@自动连线
私人会话工厂会话工厂;
@自动连线
私人InMemoryTokenStore tokenStore;
private org.hibernate.Session getCurrentSession(){
返回sessionFactory.getCurrentSession();
}
公共用户详细信息getByUsername(字符串用户名){
MyUser=新的MyUser();
user.setUserName(用户名);
Query Query=getCurrentSession().createQuery(“来自用户名=:usrName的用户”);
setParameter(“usrName”,用户名);
List getUser=query.List();
User act=getUser.get(0);
user.setPassword(act.getPassword());
user.setUserId(act.getUserId());
user.setAuthorities(getAuthorities(act.getUserId());
返回用户;
}
public BaseClientDetails getByClientId(字符串clientId){
System.out.println(“***OauthRepository.getByClientId”+clientId);
Query Query=getCurrentSession().createQuery(“来自OauthClientDetails,其中clientId=:clientId”);
setParameter(“clientId”,clientId);
List getClient=query.List();
OauthClientDetails oauthClient=getClient.get(0);
BaseClientDetails=新的BaseClientDetails();
setClientId(oauthClient.getClientId());
List grantTypesList=Arrays.asList(oauthClient.getAuthorizedGrantTypes().split(“,”);
详细信息。setAuthorizedGrantTypes(grantTypesList);
setClientSecret(oauthClient.getClientSecret());
退货详情;
}
/**
*基于数字角色检索{@link GrantedAuthority}的集合
*@param角色数字角色
*@返回{@link GrantedAuthority的集合
*/
公共集合权限(整数角色){
List authList=GetGrantedAuthories(getRoles(role));
返回authList;
}
/**
*将数字角色转换为等效的角色列表
*@param角色数字角色
*@将角色列表作为{@link String}列表返回
*/
公共列表getRoles(整数角色){
列表角色=新的ArrayList();
Query Query=getCurrentSession().createQuery(“来自UserRole,其中userID=:userID”);
setParameter(“userId”,角色);
List getUser=query.List();
UserRole actRole=getUser.get(0);
roles.add(actRole.getRole());
返回角色;
}
/**
*将{@link String}角色包装到{@link SimpleGrantedAuthority}对象
*@param角色{@link String}个角色
*@已授予权限的返回列表
*/
公共静态列表GetGrantedAuthories(列表角色){
列表权限=新建ArrayList();
for(字符串角色:角色){
权限。添加(新授权权限impl(角色));
}
返回当局;
}
}
servlet-context.xml:

            <?xml version="1.0" encoding="UTF-8"?>
        <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:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
              xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
          http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
              <!-- @author Nagesh.Chauhan(neel4soft@gmail.com) -->
              <context:annotation-config />
            <context:component-scan base-package="com.example.myproject" />
              <mvc:annotation-driven />

              <bean id="multipartResolver"
            class="org.springframework.web.multipart.commons.CommonsMultipartResolver">      

            <!-- one of the properties available; the maximum file size in bytes -->
             <property name="maxUploadSize" value="1000000000" />
              </bean>      

              <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/MyDatabase"/>
            <property name="username" value="username"/>
            <property name="password" value="password"/>
            <property name="validationQuery" value="SELECT 1"/>
          </bean>

          <!-- Hibernate Session Factory -->
          <bean id="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
            <property name="dataSource" ref="myDataSource"/>
            <property name="packagesToScan">
              <array>
                <value>com.example.myproject</value>
              </array>
            </property>
            <property name="hibernateProperties">
              <value>
                hibernate.dialect=org.hibernate.dialect.MySQLDialect
              </value>
            </property>
          </bean>
          <!-- Hibernate Transaction Manager -->
          <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
            <property name="sessionFactory" ref="mySessionFactory"/>
          </bean>

          <!-- Activates annotation based transaction management -->
          <tx:annotation-driven transaction-manager="transactionManager"/>
        </beans>

com.example.myproject
hibernate.dialogue=org.hibernate.dialogue.mysqldialogue