我如何通过 Spring Security 创建 oauth 2 用户名密码流

Posted

技术标签:

【中文标题】我如何通过 Spring Security 创建 oauth 2 用户名密码流【英文标题】:how can i create oauth 2 username password flow over spring security 【发布时间】:2011-12-14 23:52:59 【问题描述】:

我正在尝试在 Spring Security 上实现 oauth2 用户名密码流 但我找不到任何文档和示例代码 我正在查看 sparklr 和 tonr insode oauth2 样本 我怎样才能实现它 oauth2 2 legged 我怎样才能禁用登录表单

    <form-login authentication-failure-url="/login.jsp" default-target-url="/index.jsp" login-page="/login.jsp"
        login-processing-url="/login.do" />
    <logout logout-success-url="/index.jsp" logout-url="/logout.do" />
    <anonymous />
    <custom-filter ref="oauth2ProviderFilter" after="EXCEPTION_TRANSLATION_FILTER" />
</http>

【问题讨论】:

还有一个堆栈溢出的例子:***.com/questions/5431359/… 这可能会有所帮助:***.com/a/48586779/1279002 【参考方案1】:

默认的 sparklr 也支持用户名和密码流, 这很容易,您只需要编写客户端客户端如下所示: 最后我成功了;

public class App 

private static RestTemplate client=getRestTemplate();

    private static int DEFAULT_PORT = 8080;

private static String DEFAULT_HOST = "localhost";

private static int port=DEFAULT_PORT;

private static String hostName = DEFAULT_HOST;


 public static  void main(String[] args) throws IOException 
    try 
        testHappyDayWithForm();
     catch (Exception ex) 
        Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
    



public static void testHappyDayWithForm() throws Exception 

    MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>();
    formData.add("grant_type", "password");
    formData.add("client_id", "my-trusted-client");
    formData.add("scope", "read");
    formData.add("username", "muhammed");
    formData.add("password", "1234");

    ResponseEntity<String> response = postForString("/sparklr/oauth/token", formData);
    System.out.println( response.getStatusCode());
    System.out.println(response.getHeaders().getFirst("Cache-Control"));

    DefaultOAuth2SerializationService serializationService = new DefaultOAuth2SerializationService();
    OAuth2AccessToken accessToken = serializationService.deserializeJsonAccessToken(new ByteArrayInputStream(
            response.getBody().getBytes()));

    // now try and use the token to access a protected resource.

    // first make sure the resource is actually protected.
    //assertNotSame(HttpStatus.OK, serverRunning.getStatusCode("/sparklr/photos?format=json"));

    // now make sure an authorized request is valid.
    HttpHeaders headers = new HttpHeaders();
    headers.set("Authorization", String.format("%s %s", OAuth2AccessToken.BEARER_TYPE, accessToken.getValue()));
    //assertEquals(HttpStatus.OK, serverRunning.getStatusCode("/sparklr/photos?format=json", headers));


    public static ResponseEntity<String> postForString(String path, MultiValueMap<String, String> formData) 
    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_FORM_URLENCODED));
            System.out.println(getUrl(path));
    return client.exchange(getUrl(path), HttpMethod.POST, new HttpEntity<MultiValueMap<String, String>>(formData,
            headers), String.class);

    public static String getUrl(String path) 
    if (!path.startsWith("/")) 
        path = "/" + path;
    
    return "http://" + hostName + ":" + port + path;


    public static RestTemplate getRestTemplate() 
    RestTemplate client = new RestTemplate();
    CommonsClientHttpRequestFactory requestFactory = new CommonsClientHttpRequestFactory() 
        @Override
        protected void postProcessCommonsHttpMethod(HttpMethodBase httpMethod) 
            httpMethod.setFollowRedirects(false);
            // We don't want stateful conversations for this test
            httpMethod.getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
        
    ;
    client.setRequestFactory(requestFactory);
    client.setErrorHandler(new ResponseErrorHandler() 
        // Pass errors through in response entity for status code analysis
        public boolean hasError(ClientHttpResponse response) throws IOException 
            return false;
        

        public void handleError(ClientHttpResponse response) throws IOException 
        
    );
    return client;

【讨论】:

以上是关于我如何通过 Spring Security 创建 oauth 2 用户名密码流的主要内容,如果未能解决你的问题,请参考以下文章

spring security中如何通过用户id查询用户?

如何在 Spring Security 中自定义“错误凭据”错误响应?

如何使用spring-security通过用户名和密码登录?

如何阻止 Spring Security 创建新会话?

如何创建数据类实现 Spring Security 特定的 UserDetails

Grails/Spring Security:无法使用新创建的用户登录