首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于IOS不与Grails OAuth 2提供程序合作的GTM OAuth

用于IOS不与Grails OAuth 2提供程序合作的GTM OAuth
EN

Stack Overflow用户
提问于 2014-03-24 08:53:20
回答 1查看 468关注 0票数 0

我目前正在开发一个IOS应用程序,我想使用OAuth来使用我们现有的Grails系统来验证这个应用程序。grails系统使用下面链接中的插件安装了OAuth2提供程序:

代码语言:javascript
复制
https://github.com/adaptivecomputing/grails-spring-security-oauth2-provider

OAuth提供程序是设置好的,它确实可以工作,因为我已经测试了下面所示的URL,并且一旦授予访问权限,我就会得到一个预期的授权代码:

代码语言:javascript
复制
http://localhost:8080/app/oauth/authorize?response_type=code&client_id=clientId&redirect_uri=http://localhost:8080/app/

我遇到的问题是,当我使用google的GTM OAuth插件用于IOS时,我将其设置如下:

代码语言:javascript
复制
static NSString *const kMyClientID = @"1";
static NSString *const kMyClientSecret = @"secret";
static NSString *const kKeychainItemName = @"systemKeychain";

- (GTMOAuth2Authentication *)systemAuth
{

    // Set the token URL to the system token endpoint.
    NSURL *tokenURL = [NSURL URLWithString:@"http://www.systemurl.co.uk/oauth/token"];

    // Set a bogus redirect URI. It won't actually be used as the redirect will
    // be intercepted by the OAuth library and handled in the app.
    NSString *redirectURI = @"http://www.systemurl.co.uk/";

    GTMOAuth2Authentication *auth;
    auth = [GTMOAuth2Authentication authenticationWithServiceProvider:@"SYSTEM API"
                                                             tokenURL:tokenURL
                                                          redirectURI:redirectURI
                                                             clientID:kMyClientID
                                                         clientSecret:kMyClientSecret];

    return auth;
}

- (void)authorize:(NSString *)service
{
    GTMOAuth2Authentication *auth = [self systemAuth];

    // Prepare the Authorization URL. We will pass in the name of the service
    // that we wish to authorize with.
    NSURL *authURL = [NSURL URLWithString:[NSString stringWithFormat:@"http://www.systemurl.co.uk/oauth/authorize"]];

    // Display the authentication view
    GTMOAuth2ViewControllerTouch *viewController;
    viewController = [ [GTMOAuth2ViewControllerTouch alloc] initWithAuthentication:auth
                                                                  authorizationURL:authURL
                                                                  keychainItemName:kKeychainItemName
                                                                          delegate:self
                                                                  finishedSelector:@selector(viewController:finishedWithAuth:error:)];
    [viewController setBrowserCookiesURL:[NSURL URLWithString:@"http://www.systemurl.co.uk/"]];

    // Push the authentication view to our navigation controller instance
    [ [self navigationController] pushViewController:viewController animated:YES];
}


- (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController
      finishedWithAuth:(GTMOAuth2Authentication *)auth
                 error:(NSError *)error
{
    if (error != nil)
    {
        // Authentication failed
        UIAlertView *alertView = [ [UIAlertView alloc] initWithTitle:@"Authorization Failed"
                                                             message:[error localizedDescription]
                                                            delegate:self
                                                   cancelButtonTitle:@"Dismiss"
                                                   otherButtonTitles:nil];
        [alertView show];
    }
    else
    {
        // Authentication succeeded

        // Assign the access token to the instance property for later use
        self.accessToken = auth.accessToken;

        // Display the access token to the user
        UIAlertView *alertView = [ [UIAlertView alloc] initWithTitle:@"Authorization Succeeded"
                                                             message:[NSString stringWithFormat:@"Access Token: %@", auth.accessToken]
                                                            delegate:self
                                                   cancelButtonTitle:@"Dismiss"
                                                   otherButtonTitles:nil];
        [alertView show];
    }
}

问题是,当我运行上面的代码时,它会很好地将我重定向到系统,然后我登录,然后页面出现,我允许我访问这个应用程序,然后我点击“授权”,应用程序会显示一个警告视图,其中有一个错误500。

于是我回到Grails系统,查看日志,看看发生了什么,我注意到应用程序传递的url是:

代码语言:javascript
复制
"GET /oauth/authorize?client_id=1&redirect_uri=http%3A%2F%2Fwww.systemurl.co.uk%2F&response_type=code HTTP/1.1" 302 -

"GET /oauth/authorize?client_id=1&redirect_uri=http%3A%2F%2Fwww.systemurl.co.uk%2F&response_type=code HTTP/1.1" 200 6923

"POST /oauth/authorize?client_id=1&redirect_uri=http%3A%2F%2Fwww.systemurl.co.uk%2F&response_type=code HTTP/1.1" 302 -

系统中的错误500消息如下所示:

代码语言:javascript
复制
2014-03-24 08:25:53,081 [http-8080-2] ERROR errors.GrailsExceptionResolver  - NoSuchClientException occurred when processing request: [POST] /oauth/token - parameters:
client_secret: secret
grant_type: authorization_code
redirect_uri: http://www.systemurl.co.uk/
code: 4bf5Se
client_id: 1
No client with requested id: testing. Stacktrace follows:
org.springframework.security.oauth2.provider.NoSuchClientException: No client with requested id: testing
    at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:179)
    at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
    at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.java:53)
    at grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:49)
    at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:82)
    at java.lang.Thread.run(Thread.java:722)

现在,上面的错误会告诉我,由于某种原因,用户名被用作客户端id,我不知道为什么,因为用户名和密码正在grails系统上进行“测试”。

有谁能就这可能发生的原因提出建议吗?

提前感谢

***EDIT__*****

我已经调试了发送的HTTP请求,下面是发送来获取令牌的原始请求:

代码语言:javascript
复制
POST /oauth/token HTTP/1.1
Host: www.systemurl.co.uk
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Accept-Language: en-us
Cookie: JSESSIONID=70EB045C21084E166A34EDA88FE155C8.28151
Accept: */*
Content-Length: 130
Connection: keep-alive
User-Agent: gtm-oauth2 com.test.OAuthGTM/1.0

client_id=1&client_secret=secret&code=VaYn8M&grant_type=authorization_code&redirect_uri=http%3A%2F%2Fwww.systemurl.co.uk%2F
EN

回答 1

Stack Overflow用户

发布于 2014-06-04 22:44:22

简单的回答是:"client_id=public",然后它就能工作了。

长话短说:

如果通过代码进行调试,您将发现异常是在InMemoryClientDetailsService中抛出的。

在Grails版本2.2.4中,代码如下所示

代码语言:javascript
复制
private Map<String, ? extends ClientDetails> clientDetailsStore = new HashMap<String, ClientDetails>();

  public ClientDetails loadClientByClientId(String clientId) throws OAuth2Exception {
    ClientDetails details = clientDetailsStore.get(clientId);
    if (details == null) {
      throw new InvalidClientException("Client not found: " + clientId);
    }
    return details;
  }

在地图中,clientDetailsStore只是一个“公共”值

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22604741

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档