GTM OAuth for IOS不与Grails OAuth 2提供程序一起工作
我目前正在开发一个IOS应用程序,我想使用OAuth使用我们现有的Grails系统来验证这个应用程序。grails系统有一个OAuth2提供程序设置,使用下面链接中的插件:GTM OAuth for IOS不与Grails OAuth 2提供程序一起工作,grails,oauth,gtm-oauth2,Grails,Oauth,Gtm Oauth2,我目前正在开发一个IOS应用程序,我想使用OAuth使用我们现有的Grails系统来验证这个应用程序。grails系统有一个OAuth2提供程序设置,使用下面链接中的插件: https://github.com/adaptivecomputing/grails-spring-security-oauth2-provider OAuth提供程序已经设置好,它可以正常工作,因为我已经测试了如下所示的URL,并且在授予访问权限后,我确实获得了预期的授权代码: http://localhost:808
https://github.com/adaptivecomputing/grails-spring-security-oauth2-provider
OAuth提供程序已经设置好,它可以正常工作,因为我已经测试了如下所示的URL,并且在授予访问权限后,我确实获得了预期的授权代码:
http://localhost:8080/app/oauth/authorize?response_type=code&client_id=clientId&redirect_uri=http://localhost:8080/app/
我遇到的问题是,当我从谷歌使用用于IOS的GTM OAuth插件时,我将其设置如下:
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是:
"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消息如下所示:
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系统上“测试”
有人能就为什么会发生这种情况提供一些建议吗
提前谢谢
***编辑******
我已经调试了正在发送的HTTP请求,下面是为获取令牌而发送的原始请求:
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
简单的回答是:“client_id=public”,然后它就可以工作了
答案很长:
如果对代码进行调试,您会发现异常是在MemoryClientDetailsService中抛出的
在Grails版本2.2.4中,代码如下所示
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;
}
private-Map-clientdetailssstore=new-HashMap();
public ClientDetails loadClientByClientId(字符串clientId)引发OAuth2Exception{
ClientDetails=clientDetailsStore.get(clientId);
如果(详细信息==null){
抛出新的InvalidClientException(“未找到客户端:+clientId”);
}
退货详情;
}
在Map clientDetailsStore中只有一个值是“public”我在上面添加了更多细节:)