Как извлечь заявки из токена в Resource Server, в Spring Boot - PullRequest
1 голос
/ 03 февраля 2020

Мой сервер аутентификации настроен на получение проверочных учетных данных по таблице в моей базе данных с помощью токена, который я использую для передачи дополнительных утверждений - вещей, связанных с контролем доступа.

Таким образом, я написал это как это:

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    @Value("${security.signing-key}")
    private String signingKey;
    private @Autowired TokenStore tokenStore;
    private @Autowired AuthenticationManager authenticationManager;
    private @Autowired CustomUserDetailsService userDetailsService;

    private @Autowired JwtAccessTokenConverter accessTokenConverter;

    private static final Logger LOGGER = LogManager.getLogger(AuthorizationServerConfig.class);

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource oauthDataSource() {
        DataSource ds = null;
        try {
            Context initialContex = new InitialContext();
            ds = (DataSource) (initialContex.lookup("java:/jdbc/oauthdatasource"));
            if (ds != null) {
                ds.getConnection();
            }
        } catch (NamingException ex) {
            LOGGER.error("Naming exception thrown: ", ex);
        } catch (SQLException ex) {
            LOGGER.info("SQL exception thrown: ", ex);
        }
        return ds;
    }

    @Bean
    public JdbcClientDetailsService clientDetailsServices() {
        return new JdbcClientDetailsService(oauthDataSource());
    }

    @Bean
    public TokenStore tokenStore() {
        return new CustomJdbcTokenStore(oauthDataSource());
    }

    @Bean
    public ApprovalStore approvalStore() {
        return new JdbcApprovalStore(oauthDataSource());
    }

    @Bean
    public AuthorizationCodeServices authorizationCodeServices() {
        return new JdbcAuthorizationCodeServices(oauthDataSource());
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        CustomTokenEnhancer converter = new CustomTokenEnhancer();
        converter.setSigningKey(signingKey);
        return converter;
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.withClientDetails(clientDetailsServices());
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore)
                .authenticationManager(authenticationManager)
                .accessTokenConverter(accessTokenConverter)
                .userDetailsService(userDetailsService)
                .reuseRefreshTokens(false);
    }
}

Это работает очень хорошо. Когда я звоню через POSTMAN, я получаю что-то вроде этого:

{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsic2hhcmVwb3J0YWwiXSwiaW5mb19maXJzdCI6IlRoaXMgaXMgdGhlIGZpcnN0IEluZm8iLCJ1c2VyX25hbWUiOiJBdXRoZW50aWNhdGlvbiIsInNjb3BlIjpbInJlYWQiLCJ3cml0ZSIsInRydXN0Il0sImluZm9fc2Vjb25kIjoiVGhpcyBpcyB0aGUgc2Vjb25kIGluZm8iLCJleHAiOjE1ODA3MTMyOTQsImF1dGhvcml0aWVzIjpbIlJPTEVfVVNFUiJdLCJqdGkiOiI1MTg4MGJhZC00MGJiLTQ3ZTItODRjZS1lNDUyNGY1Y2Y3MzciLCJjbGllbnRfaWQiOiJzaGFyZXBvcnRhbC1jbGllbnQifQ.ABmBjwmVDb2acZtGSQrjKcCwfZwhw4R_rpW4y5JA1jY",
    "token_type": "bearer",
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsic2hhcmVwb3J0YWwiXSwiaW5mb19maXJzdCI6IlRoaXMgaXMgdGhlIGZpcnN0IEluZm8iLCJ1c2VyX25hbWUiOiJBdXRoZW50aWNhdGlvbiIsInNjb3BlIjpbInJlYWQiLCJ3cml0ZSIsInRydXN0Il0sImF0aSI6IjUxODgwYmFkLTQwYmItNDdlMi04NGNlLWU0NTI0ZjVjZjczNyIsImluZm9fc2Vjb25kIjoiVGhpcyBpcyB0aGUgc2Vjb25kIGluZm8iLCJleHAiOjE1ODA3MTM0MzQsImF1dGhvcml0aWVzIjpbIlJPTEVfVVNFUiJdLCJqdGkiOiIyZDYxMDU2ZC01ZDMwLTRhZTQtOWMxZC0zZjliYjRiOWYxOGIiLCJjbGllbnRfaWQiOiJzaGFyZXBvcnRhbC1jbGllbnQifQ.qSLpJm4QxZTIVn1WYWH7EFBS8ryjF1hsD6RSRrEBZd0",
    "expires_in": 359,
    "scope": "read write trust"
}

Теперь проблема в моем сервере ресурсов. Так было до того, как я добавил токен-энхансер на свой сервер аутентификации:

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    private @Autowired CustomAuthenticationEntryPoint entryPoint;
    private @Autowired TokenStore tokenStore;
    private static final String RESOURCE_ID = "resourceid";

    private static final Logger LOGGER = LogManager.getLogger(ResourceServerConfig.class);

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource oauthDataSource() {
        DataSource ds = null;
        try {
            Context initialContex = new InitialContext();
            ds = (DataSource) (initialContex.lookup("java:/jdbc/oauthdatasource"));
            if (ds != null) {
                ds.getConnection();
            }
        } catch (NamingException ex) {
            LOGGER.error("Naming exception thrown: ", ex);
        } catch (SQLException ex) {
            LOGGER.info("SQL exception thrown: ", ex);
        }
        return ds;
    }

    @Bean
    public TokenStore getTokenStore() {
        return new JdbcTokenStore(oauthDataSource());
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers(HttpMethod.GET, "/**").access("#oauth2.hasScope('read')")
                .antMatchers(HttpMethod.POST, "/**").access("#oauth2.hasScope('write')")
                .antMatchers(HttpMethod.PATCH, "/**").access("#oauth2.hasScope('write')")
                .antMatchers(HttpMethod.PUT, "/**").access("#oauth2.hasScope('write')")
                .antMatchers(HttpMethod.DELETE, "/**").access("#oauth2.hasScope('write')")
                .and()
                .headers().addHeaderWriter((request, response) -> {
                    response.addHeader("Access-Control-Allow-Origin", "*");
                    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
                    response.setHeader("Access-Control-Max-Age", "3600");
                    response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization");
                    if (request.getMethod().equals("OPTIONS")) {
                        response.setStatus(HttpServletResponse.SC_OK);
                    }
                })
                .and().exceptionHandling().authenticationEntryPoint(entryPoint);
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId(RESOURCE_ID).tokenStore(tokenStore).authenticationEntryPoint(entryPoint);
    }
}

I wi sh для получения информации об управлении доступом, которую я разместил в качестве дополнительных утверждений через сервер аутентификации, но я не знаю, как go об этом.

Я видел несколько примеров на inte rnet, в том числе: Как извлечь утверждения из Spring Security OAuht2 Boot в Сервер ресурсов? , но ни один из них у меня не работает. Или, может быть, я что-то упускаю.

Пожалуйста, что мне нужно добавить, чтобы сделать это возможным?

1 Ответ

0 голосов
/ 20 февраля 2020

Мне пришлось использовать стороннюю библиотеку для достижения этой цели.

Это ссылка на библиотеку: https://github.com/auth0/java-jwt

Она работает очень хорошо.

На моем сервере ресурсов я могу получить значение токена, а затем, используя библиотеку java -jwt, я могу извлечь любые утверждения, которые я установил на своем сервере авторизации:

public Map<String, Claim> getClaims() {
        Map<String, Claim> claims = new HashMap<>();

        String tokenValue = ((OAuth2AuthenticationDetails)((OAuth2Authentication) authenticationFacade.getAuthentication()).getDetails()).getTokenValue();
        try {
            DecodedJWT jwt = JWT.decode(tokenValue);
            claims = jwt.getClaims();
        } catch (JWTDecodeException ex) {
            LOGGER.info("Error decoding token value");
            LOGGER.error("Error decoding token value", ex);
        }

        return claims;
}

Чтобы узнать больше, обратитесь к документации по java -jwt.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...