-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Bearer Authentication #988
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,22 @@ | ||
package com.loopj.android.http; | ||
|
||
/* | ||
Android Asynchronous Http Client | ||
Copyright (c) 2011 James Smith <james@loopj.com> | ||
https://loopj.com | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
https://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package com.loopj.android.http; | ||
|
||
import android.content.Context; | ||
import android.media.session.MediaSession; | ||
import android.os.Looper; | ||
|
||
import java.io.IOException; | ||
|
@@ -50,6 +48,7 @@ | |
import cz.msebera.android.httpclient.HttpResponse; | ||
import cz.msebera.android.httpclient.HttpResponseInterceptor; | ||
import cz.msebera.android.httpclient.HttpVersion; | ||
import cz.msebera.android.httpclient.auth.AuthSchemeRegistry; | ||
import cz.msebera.android.httpclient.auth.AuthScope; | ||
import cz.msebera.android.httpclient.auth.AuthState; | ||
import cz.msebera.android.httpclient.auth.Credentials; | ||
|
@@ -76,6 +75,7 @@ | |
import cz.msebera.android.httpclient.conn.ssl.SSLSocketFactory; | ||
import cz.msebera.android.httpclient.entity.HttpEntityWrapper; | ||
import cz.msebera.android.httpclient.impl.auth.BasicScheme; | ||
import cz.msebera.android.httpclient.impl.client.BasicCredentialsProvider; | ||
import cz.msebera.android.httpclient.impl.client.DefaultHttpClient; | ||
import cz.msebera.android.httpclient.impl.conn.tsccm.ThreadSafeClientConnManager; | ||
import cz.msebera.android.httpclient.params.BasicHttpParams; | ||
|
@@ -251,6 +251,11 @@ public void process(HttpResponse response, HttpContext context) { | |
httpClient.addRequestInterceptor(new HttpRequestInterceptor() { | ||
@Override | ||
public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException { | ||
|
||
AuthSchemeRegistry authSchemeRegistry = new AuthSchemeRegistry(); | ||
authSchemeRegistry.register("Bearer", new BearerAuthSchemeFactory()); | ||
context.setAttribute(ClientContext.AUTHSCHEME_REGISTRY, authSchemeRegistry); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't like this line, it means we're overriding any AUTHSCHEME_REGISTRY already contained by underlying HttpContext ? This should be enabled on-demand, not as only AuthScheme available from library |
||
|
||
AuthState authState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE); | ||
CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute( | ||
ClientContext.CREDS_PROVIDER); | ||
|
@@ -259,7 +264,11 @@ public void process(final HttpRequest request, final HttpContext context) throws | |
if (authState.getAuthScheme() == null) { | ||
AuthScope authScope = new AuthScope(targetHost.getHostName(), targetHost.getPort()); | ||
Credentials creds = credsProvider.getCredentials(authScope); | ||
if (creds != null) { | ||
if(creds instanceof TokenCredentials) { | ||
authState.setAuthScheme(new BearerAuthSchemeFactory.BearerAuthScheme()); | ||
authState.setCredentials(creds); | ||
} | ||
else if (creds != null) { | ||
authState.setAuthScheme(new BasicScheme()); | ||
authState.setCredentials(creds); | ||
} | ||
|
@@ -791,6 +800,29 @@ public void removeHeader(String header) { | |
clientHeaderMap.remove(header); | ||
} | ||
|
||
/** | ||
* Sets bearer authentication for the request. Uses AuthScope.ANY. This is the same as | ||
* setBearerAuth('token',AuthScope.ANY, false) | ||
* @param token Bearer Token | ||
*/ | ||
public void setBearerAuth(String token) { | ||
setBearerAuth(token, AuthScope.ANY, false); | ||
} | ||
|
||
|
||
/** | ||
* Sets bearer authentication for the request. You should pass in your AuthScope for security. It | ||
* should be like this setBearerAuth("token", new AuthScope("host",port,AuthScope.ANY_REALM), false) | ||
* @param token Bearer Token | ||
* @param scope an AuthScope object | ||
* @param preemptive sets authorization in preemptive manner | ||
*/ | ||
public void setBearerAuth(String token, AuthScope scope, boolean preemptive) { | ||
TokenCredentials credentials = new TokenCredentials(token); | ||
setCredentials(scope, credentials); | ||
setAuthenticationPreemptive(preemptive); | ||
} | ||
|
||
/** | ||
* Sets basic authentication for the request. Uses AuthScope.ANY. This is the same as | ||
* setBasicAuth('username','password',AuthScope.ANY) | ||
|
@@ -1635,4 +1667,4 @@ public void consumeContent() throws IOException { | |
super.consumeContent(); | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package com.loopj.android.http; | ||
|
||
import cz.msebera.android.httpclient.Header; | ||
import cz.msebera.android.httpclient.HttpRequest; | ||
import cz.msebera.android.httpclient.auth.AUTH; | ||
import cz.msebera.android.httpclient.auth.AuthScheme; | ||
import cz.msebera.android.httpclient.auth.AuthSchemeFactory; | ||
import cz.msebera.android.httpclient.auth.AuthenticationException; | ||
import cz.msebera.android.httpclient.auth.ContextAwareAuthScheme; | ||
import cz.msebera.android.httpclient.auth.Credentials; | ||
import cz.msebera.android.httpclient.auth.MalformedChallengeException; | ||
import cz.msebera.android.httpclient.message.BufferedHeader; | ||
import cz.msebera.android.httpclient.params.HttpParams; | ||
import cz.msebera.android.httpclient.protocol.HttpContext; | ||
import cz.msebera.android.httpclient.util.CharArrayBuffer; | ||
|
||
/** | ||
* Created by chase on 08/10/2015. | ||
*/ | ||
public class BearerAuthSchemeFactory implements AuthSchemeFactory { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add proper copyright claim here |
||
|
||
@Override | ||
public AuthScheme newInstance(HttpParams params) { | ||
return new BearerAuthScheme(); | ||
} | ||
|
||
public static class BearerAuthScheme implements ContextAwareAuthScheme { | ||
private boolean complete = false; | ||
|
||
@Override | ||
public void processChallenge(Header header) throws MalformedChallengeException { | ||
this.complete = true; | ||
} | ||
|
||
@Override | ||
public Header authenticate(Credentials credentials, HttpRequest request) throws AuthenticationException { | ||
return authenticate(credentials, request, null); | ||
} | ||
|
||
@Override | ||
public Header authenticate(Credentials credentials, HttpRequest request, HttpContext httpContext) | ||
throws AuthenticationException { | ||
CharArrayBuffer buffer = new CharArrayBuffer(32); | ||
buffer.append(AUTH.WWW_AUTH_RESP); | ||
buffer.append(": Bearer "); | ||
buffer.append(credentials.getUserPrincipal().getName()); | ||
return new BufferedHeader(buffer); | ||
} | ||
|
||
@Override | ||
public String getSchemeName() { | ||
return "Bearer"; | ||
} | ||
|
||
@Override | ||
public String getParameter(String name) { | ||
return null; | ||
} | ||
|
||
@Override | ||
public String getRealm() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public boolean isConnectionBased() { | ||
return false; | ||
} | ||
|
||
@Override | ||
public boolean isComplete() { | ||
return this.complete; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.loopj.android.http; | ||
|
||
/** | ||
* Created by chase on 08/10/2015. | ||
*/ | ||
import java.security.Principal; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add correct copyright |
||
|
||
import cz.msebera.android.httpclient.auth.BasicUserPrincipal; | ||
import cz.msebera.android.httpclient.auth.Credentials; | ||
|
||
public class TokenCredentials implements Credentials { | ||
private Principal userPrincipal; | ||
|
||
public TokenCredentials(String token) { | ||
this.userPrincipal = new BasicUserPrincipal(token); | ||
} | ||
|
||
@Override | ||
public Principal getUserPrincipal() { | ||
return userPrincipal; | ||
} | ||
|
||
@Override | ||
public String getPassword() { | ||
return null; | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see MediaSession used anywhere else than in this import