在 Spring 安全中接收令牌的基本身份验证

Basic Auth to Receive Token in Spring Security

我正在实施 RESTful API,用户必须在其中进行身份验证。我希望用户 POST 他们的凭据以便接收 JSON 网络令牌 (JWT),然后将其用于会话的其余部分。我还没有找到任何好的信息来源来设置它。特别是,我在使用过滤器时遇到了问题。有人有任何信息或教程可以帮助我进行设置吗?

这是来自 Spring Security OAuth github 的工作示例代码。 https://github.com/spring-projects/spring-security-oauth/tree/master/tests/annotation/jwt

您可能甚至不需要像上面的示例那样弄乱过滤器。如果您有定制需求,请post一些示例代码。

Stormpath have quite a straightforward solution for achieving Oauth. Please take a look at Using Stormpath for API Authentication 的人。

总而言之,您的解决方案如下所示:

  1. 您将使用 Stormpath Java SDK 轻松委派所有用户管理需求。
  2. 当用户按下登录按钮时,您的前端将通过其 REST API 将凭据安全地发送到您的后端。
    1. 顺便说一下,您也可以将 login/register/logout 功能完全委托给 Servlet Plugin。 Stormpath 还支持 Google、Facebook、LinkedIn 和 Github 登录。
  3. 您的后端将尝试根据 Stormpath 后端对用户进行身份验证,结果将 return access token

    /**
     * Authenticates via username (or email) and password and returns a new access token using the Account's ApiKey
     */
    public String getAccessToken(String usernameOrEmail, String password) {
        ApiKey apiKey = null;
        try {
            AuthenticationRequest request = new UsernamePasswordRequest(usernameOrEmail, password);
            AuthenticationResult result = application.authenticateAccount(request);
            Account account = result.getAccount();
            ApiKeyList apiKeys = account.getApiKeys();
            for (ApiKey ak : apiKeys) {
                apiKey = ak;
                break;
            }
            if (apiKey == null) {
                //this account does not yet have an apiKey
                apiKey = account.createApiKey();
            }
        } catch (ResourceException exception) {
            System.out.println("Authentication Error: " + exception.getMessage());
            throw exception;
        }
    
        return getAccessToken(apiKey);
    }
    
    private String getAccessToken(ApiKey apiKey) {
        HttpRequest request = createOauthAuthenticationRequest(apiKey);
        AccessTokenResult accessTokenResult = (AccessTokenResult) application.authenticateApiRequest(request);
        return accessTokenResult.getTokenResponse().getAccessToken();
    }
    
    
    private HttpRequest createOauthAuthenticationRequest(ApiKey apiKey) {
        try {
            String credentials = apiKey.getId() + ":" + apiKey.getSecret();
    
            Map<String, String[]> headers = new LinkedHashMap<String, String[]>();
            headers.put("Accept", new String[]{"application/json"});
            headers.put("Content-Type", new String[]{"application/x-www-form-urlencoded"});
            headers.put("Authorization", new String[]{"Basic " + Base64.encodeBase64String(credentials.getBytes("UTF-8"))});
    
            Map<String, String[]> parameters = new LinkedHashMap<String, String[]>();
            parameters.put("grant_type", new String[]{"client_credentials"});
    
            HttpRequest request = HttpRequests.method(HttpMethod.POST)
                    .headers(headers)
                    .parameters(parameters)
                    .build();
            return request;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    
  4. 然后,对于每个经过身份验证的请求,您的后端将执行:

    /** This is your protected API */
    public void sayHello(String accessToken) throws OauthAuthenticationException {
        try {
            if (verify(accessToken)) {
                doStartEngines(); //Here you will actually call your internal doStartEngines() operation
            }
        } catch (OauthAuthenticationException e) {
            System.out.print("[Server-side] Engines not started. accessToken could not be verified: " + e.getMessage());
            throw e;
        }
    }
    
    private boolean verify(String accessToken) throws OauthAuthenticationException {
        HttpRequest request = createRequestForOauth2AuthenticatedOperation(accessToken);
        OauthAuthenticationResult result = application.authenticateOauthRequest(request).execute();
        System.out.println(result.getAccount().getEmail() + " was successfully verified");
        return true;
    }
    
    private HttpRequest createRequestForOauth2AuthenticatedOperation(String token) {
        try {
            Map<String, String[]> headers = new LinkedHashMap<String, String[]>();
            headers.put("Accept", new String[]{"application/json"});
            headers.put("Authorization", new String[]{"Bearer " + token});
            HttpRequest request = HttpRequests.method(HttpMethod.GET)
                    .headers(headers)
                    .build();
            return request;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    

所有这些都不需要任何特殊的 Spring 安全配置,这是简单的 Java 代码,您可以在任何框架中 运行。

请查看here了解更多信息。

希望对您有所帮助!

免责声明,我是活跃的 Stormpath 贡献者。