Skip to Content.
Sympa Menu

idok-commit - [idok-commit] idok commit r216 - branches/rest/java/ch/idok/service/server/rest

idok-commit AT lists.psi.ch

Subject: Commit emails of the iDok project

List archive

[idok-commit] idok commit r216 - branches/rest/java/ch/idok/service/server/rest


Chronological Thread 
  • From: "AFS account Roman Geus" <geus AT savannah.psi.ch>
  • To: idok-commit AT lists.psi.ch
  • Subject: [idok-commit] idok commit r216 - branches/rest/java/ch/idok/service/server/rest
  • Date: Wed, 17 Sep 2008 15:01:48 +0200
  • List-archive: <https://lists.web.psi.ch/pipermail/idok-commit/>
  • List-id: Commit emails of the iDok project <idok-commit.lists.psi.ch>

Author: geus
Date: Wed Sep 17 15:01:48 2008
New Revision: 216

Log:
Implemented fallback to basic authentication, tested using FF3. IE6-8, Opera,
Safari

Modified:
branches/rest/java/ch/idok/service/server/rest/NegotiateFilter.java

Modified: branches/rest/java/ch/idok/service/server/rest/NegotiateFilter.java
==============================================================================
--- branches/rest/java/ch/idok/service/server/rest/NegotiateFilter.java
(original)
+++ branches/rest/java/ch/idok/service/server/rest/NegotiateFilter.java Wed
Sep 17 15:01:48 2008
@@ -44,8 +44,6 @@
* Tested with Java 6.
*
* Does not work with Java 5, because SPNEGO is not supported.
- *
- * TODO proper fallback to Basic when Negotiate token cannot be accepted
*/
public abstract class NegotiateFilter extends Filter {

@@ -135,6 +133,10 @@
return gssManager.createContext((GSSCredential) gssServerCreds);
}

+ /**
+ * @see org.restlet.Filter#doHandle(org.restlet.data.Request,
+ * org.restlet.data.Response)
+ */
@Override
protected int doHandle(Request request, Response response) {
Logger logger = getContext().getLogger();
@@ -142,7 +144,7 @@
ChallengeResponse cr = request.getChallengeResponse();

Subject authenticatedSubject = null;
-
+
int result = Filter.STOP;
@SuppressWarnings("unchecked")
Series<Parameter> reqHeaders = (Series<Parameter>) request
@@ -151,50 +153,88 @@
String authorizationHeader =
reqHeaders.getFirstValue("Authorization");

try {
- // Initialises the GSSContext
- GSSContext gssContext = gssInit();
-
logger.log(Level.FINEST, "Received this authorization header:
{0}",
authorizationHeader);

- Form spnegoParams = new Form();
+ Form negotiateParams = new Form();
+
+ boolean fallbackToBasic = false;

- // Reads the autorisation header
+ // Read the autorization header
if (authorizationHeader != null) {
if (authorizationHeader.startsWith("Negotiate ")) {
- /*
- * If the request contains a Negotiate auth header, the
- * token is passed to the GSS context. The token
obtained in
- * return (from the GSS API) will be sent back in the
- * response.
- */
- String spnegoOutputTokenString = "";
-
- String spnegoInputTokenString = authorizationHeader
- .substring("Negotiate ".length());
- byte[] spnegoToken;
try {
- BigInteger integerToken = new BigInteger(
- spnegoInputTokenString, 16);
- spnegoToken = integerToken.toByteArray();
- } catch (NumberFormatException e) {
- spnegoToken = Base64.decode(spnegoInputTokenString);
- }
+ /*
+ * If the request contains a Negotiate auth header,
the
+ * token is passed to the GSS context. The token
+ * obtained in return (from the GSS API) will be sent
+ * back in the response.
+ */
+
+ // Initialize the GSSContext
+ GSSContext gssContext = gssInit();
+
+ String spnegoOutputTokenString = "";
+
+ String spnegoInputTokenString = authorizationHeader
+ .substring("Negotiate ".length());
+ byte[] spnegoToken;
+ try {
+ BigInteger integerToken = new BigInteger(
+ spnegoInputTokenString, 16);
+ spnegoToken = integerToken.toByteArray();
+ } catch (NumberFormatException e) {
+ spnegoToken =
Base64.decode(spnegoInputTokenString);
+ }
+
+ if (spnegoToken.length != 0) {
+ spnegoToken = gssContext.acceptSecContext(
+ spnegoToken, 0, spnegoToken.length);
+ spnegoOutputTokenString = Base64.encode(
+ spnegoToken, false);
+ }
+
+ negotiateParams
+ .add(
+
NegotiateAuthenticationHelper.NEGOTIATE_TOKEN_PARAM_NAME,
+ spnegoOutputTokenString);
+ logger.log(Level.FINEST,
+ "Sending this Negotiate challenge: {0}",
+ spnegoOutputTokenString);

- if (spnegoToken.length != 0) {
- spnegoToken =
gssContext.acceptSecContext(spnegoToken,
- 0, spnegoToken.length);
- spnegoOutputTokenString = Base64.encode(spnegoToken,
- false);
+ if (gssContext.isEstablished()) {
+ final GSSName srcName = gssContext.getSrcName();
+ logger
+ .log(
+ Level.FINER,
+ "Authenticated via
GSS/Negotiate: {0}({1})",
+ new Object[] { srcName,
+
srcName.getStringNameType() });
+
+ // Create Subject from GSS-API token (including
TGT
+ // if available)
+ try {
+ GSSCredential gssCred = gssContext
+ .getDelegCred();
+ authenticatedSubject = GSSUtil.createSubject(
+ gssContext.getSrcName(), gssCred);
+ } catch (GSSException e) {
+ authenticatedSubject = GSSUtil.createSubject(
+ gssContext.getSrcName(), null);
+ }
+ // Set identifier, so
+ // ChallengeResponse.getPrincipal() works
+ cr.setIdentifier(srcName.toString());
+ }
+ } catch (GSSException e) {
+ fallbackToBasic = true;
+ logger
+ .log(
+ Level.FINER,
+ "A GSSAPI error occured when
processing the Negotiate token, falling back to basic authentication",
+ e);
}

- spnegoParams
- .add(
-
NegotiateAuthenticationHelper.NEGOTIATE_TOKEN_PARAM_NAME,
- spnegoOutputTokenString);
- logger.log(Level.FINEST,
- "Sending this Negotiate challenge: {0}",
- spnegoOutputTokenString);
} else if (authorizationHeader.startsWith("Basic ")) {
try {
final byte[] credentialsEncoded = Base64.decode(cr
@@ -228,18 +268,22 @@
e);
}

+ // To be compatible Safari and Opera browsers, do not
offer
+ // Negotiate if Basic was sent
+ fallbackToBasic = true;
+
} else {
response.setStatus(Status.CLIENT_ERROR_UNAUTHORIZED);
}
- }
+ }

/*
- * Add challenges
+ * Add challenges to response
*/
- if (offerNegotiate) {
+ if (offerNegotiate && !fallbackToBasic) {
ChallengeRequest negotiateChallengeReq = new
ChallengeRequest(
HTTP_NEGOTIATE, null);
- negotiateChallengeReq.setParameters(spnegoParams);
+ negotiateChallengeReq.setParameters(negotiateParams);
response.getChallengeRequests().add(negotiateChallengeReq);
}

@@ -247,35 +291,6 @@
ChallengeScheme.HTTP_BASIC, realm);
response.getChallengeRequests().add(basicChallengeReq);

- if (gssContext.isEstablished()) {
- try {
- final GSSName srcName = gssContext.getSrcName();
- logger
- .log(
- Level.FINER,
- "Authenticated via GSS/Negotiate:
{0}({1})",
- new Object[] { srcName,
- srcName.getStringNameType() });
-
- // Create Subject from GSS-API token (including TGT if
- // available)
- try {
- GSSCredential gssCred = gssContext.getDelegCred();
- authenticatedSubject =
GSSUtil.createSubject(gssContext
- .getSrcName(), gssCred);
- } catch (GSSException e) {
- authenticatedSubject =
GSSUtil.createSubject(gssContext
- .getSrcName(), null);
- }
- // Set identifier, so ChallengeResponse.getPrincipal()
works
- cr.setIdentifier(srcName.toString());
- } catch (GSSException e) {
- logger.log(Level.FINER,
- "An exception occurred in NegotiateFilter", e);
- response.setStatus(Status.SERVER_ERROR_INTERNAL);
- }
- }
-
if (authenticatedSubject != null) {
// Make Subject available through request attributes
request.getAttributes().put(subjectAttributeName,
@@ -285,7 +300,6 @@
} else {
response.setStatus(Status.CLIENT_ERROR_UNAUTHORIZED);
}
-
} catch (Exception e) {
logger.log(Level.FINER, "An exception occurred in
NegotiateFilter",
e);



  • [idok-commit] idok commit r216 - branches/rest/java/ch/idok/service/server/rest, AFS account Roman Geus, 09/17/2008

Archive powered by MHonArc 2.6.19.

Top of Page