Re: [Architecture] [IS 5.5.0] Conditional steps based on HTTP context

2018-01-22 Thread Ruwan Abeykoon
Hi Sathya,
We can use the following way when we address cookies. [1]

instead of (which is cumbersome in developer PoV)
context.response.headers["Set-Cookie"] = "testcookie=1FD36B269C61; Path=/;
Secure; HttpOnly; Expires=Wed, 21 Jan 2018 07:28:00 GMT"

e.g.

cookies
  // set a regular cookie
  .set( "unsigned", "foo", { httpOnly: false } )

  // set a signed cookie
  .set( "signed", "bar", { signed: true } )

  // mimic a signed cookie, but with a bogus signature
  .set( "tampered", "baz" )
  .set( "tampered.sig", "bogus" )


[1] https://www.npmjs.com/package/cookies


Cheers,
Ruwan



On Thu, Jan 18, 2018 at 11:56 PM, Sathya Bandara  wrote:

> Hi,
>
> Thanks for the suggestion. I have modified the existing
> DefaultRequestCoordinator and removed ConditionalRequestCoordinator since
> there are no functional level changes in DefaultRequestCoordinator.
>
> Following is a sample script to enforce conditional authentication based
> on the HTTP context.
>
>
> function(context) {
> executeStep({
> id: '1',
> on: {
> success: function (context) {
>
> if (context.request.cookies.testcookie) {
> log.info("--- cookie testcookie found in
> request.");
> log.info("--- cookie testcookie.value: "
> + context.request.cookies.testcookie.value);
> log.info("--- cookie testcookie.domain: "
> + context.request.cookies.testcookie.domain);
> log.info("--- cookie testcookie.max-age: "
> + context.request.cookies.testcookie["max-age"]);
> log.info("--- cookie testcookie.path: " +
> context.request.cookies.testcookie.path);
> log.info("--- cookie testcookie.secure: "
> + context.request.cookies.testcookie.secure);
> log.info("--- cookie testcookie.version: "
> + context.request.cookies.testcookie.version);
> log.info("--- cookie testcookie.httpOnly:
> " + context.request.cookies.testcookie.httpOnly);
> } else {
> executeStep({
> id: '2',
> on: {
> success: function (context)
> {
> log.info("--- setting cookie
> : testcookie");
>   context.response.headers["Set-Cookie"]
> = "testcookie=1FD36B269C61; Path=/; Secure; HttpOnly; Expires=Wed, 21 Jan
> 2018 07:28:00 GMT"
> }
> }
> });
> }
> }
> }
> });
> }
>
>
> In the above script, we define a cookie called *testcookie*. At the
> initial authentication stage, the user has to go through both step 1 and
> step 2. If authentication is successful, we will set a cookie (testcookie)
> in the user's browser. At the next login session, if this cookie is found
> in the authentication request, user will be authenticated from the first
> step itself and the second authentication step will get skipped.
>
> Thanks,
> Sathya
>
> On Wed, Jan 17, 2018 at 6:56 PM, Ruwan Abeykoon  wrote:
>
>> Hi Sathya,
>>
>> We can enhance the DefaultRequestCoordinator itself, rather than
>> extending and creating new coordinator, as there is no functional change
>> done by adding the "request" and "response" to authentication context.
>>
>> Cheers,
>> Ruwan
>>
>> On Wed, Jan 17, 2018 at 10:40 AM, Sathya Bandara  wrote:
>>
>>> Hi all,
>>>
>>> We are currently working on improving the conditional authentication
>>> support using JavaScript feature [1] to be able to handle authentication
>>> conditions based on HTTP context.
>>>
>>> Following is the approach taken to achieve this requirement.
>>>
>>> In order to store the HTTP request and response I have modified the
>>> default AuthenticationContext class to have additional state variables for
>>> the authentication request and response(current request and response).
>>> These variables are declared as transient such that they will not be used
>>> for the object state at serialization. Furthermore, an additional variable
>>> will be used to keep a reference to the initial authentication request
>>> (initialRequest). When the second request comes, we will only update the
>>> current request and response variables.
>>>
>>> The DefaultRequestCoordinator will be replaced with
>>> ConditionalRequestCoordinator. In ConditionalRequestCordinator, inside
>>> initializeFlow() method which gets called for the initial authentication
>>> request, we instantiate an AuthenticationContext object. To this object, I
>>> will set the current request, current response and initial request which is
>>> the same as current request for the initial case. From the second request
>>> for the ConditionalRequestCoordinator, 

Re: [Architecture] [IS 5.5.0] Conditional steps based on HTTP context

2018-01-18 Thread Sathya Bandara
Hi,

Thanks for the suggestion. I have modified the existing
DefaultRequestCoordinator and removed ConditionalRequestCoordinator since
there are no functional level changes in DefaultRequestCoordinator.

Following is a sample script to enforce conditional authentication based on
the HTTP context.


function(context) {
executeStep({
id: '1',
on: {
success: function (context) {

if (context.request.cookies.testcookie) {
log.info("--- cookie testcookie found in
request.");
log.info("--- cookie testcookie.value: " +
context.request.cookies.testcookie.value);
log.info("--- cookie testcookie.domain: " +
context.request.cookies.testcookie.domain);
log.info("--- cookie testcookie.max-age: "
+ context.request.cookies.testcookie["max-age"]);
log.info("--- cookie testcookie.path: " +
context.request.cookies.testcookie.path);
log.info("--- cookie testcookie.secure: " +
context.request.cookies.testcookie.secure);
log.info("--- cookie testcookie.version: "
+ context.request.cookies.testcookie.version);
log.info("--- cookie testcookie.httpOnly: "
+ context.request.cookies.testcookie.httpOnly);
} else {
executeStep({
id: '2',
on: {
success: function (context)
{
log.info("--- setting cookie :
testcookie");

context.response.headers["Set-Cookie"] = "testcookie=1FD36B269C61;
Path=/; Secure; HttpOnly; Expires=Wed, 21 Jan 2018 07:28:00 GMT"
}
}
});
}
}
}
});
}


In the above script, we define a cookie called *testcookie*. At the initial
authentication stage, the user has to go through both step 1 and step 2. If
authentication is successful, we will set a cookie (testcookie) in the
user's browser. At the next login session, if this cookie is found in the
authentication request, user will be authenticated from the first step
itself and the second authentication step will get skipped.

Thanks,
Sathya

On Wed, Jan 17, 2018 at 6:56 PM, Ruwan Abeykoon  wrote:

> Hi Sathya,
>
> We can enhance the DefaultRequestCoordinator itself, rather than
> extending and creating new coordinator, as there is no functional change
> done by adding the "request" and "response" to authentication context.
>
> Cheers,
> Ruwan
>
> On Wed, Jan 17, 2018 at 10:40 AM, Sathya Bandara  wrote:
>
>> Hi all,
>>
>> We are currently working on improving the conditional authentication
>> support using JavaScript feature [1] to be able to handle authentication
>> conditions based on HTTP context.
>>
>> Following is the approach taken to achieve this requirement.
>>
>> In order to store the HTTP request and response I have modified the
>> default AuthenticationContext class to have additional state variables for
>> the authentication request and response(current request and response).
>> These variables are declared as transient such that they will not be used
>> for the object state at serialization. Furthermore, an additional variable
>> will be used to keep a reference to the initial authentication request
>> (initialRequest). When the second request comes, we will only update the
>> current request and response variables.
>>
>> The DefaultRequestCoordinator will be replaced with
>> ConditionalRequestCoordinator. In ConditionalRequestCordinator, inside
>> initializeFlow() method which gets called for the initial authentication
>> request, we instantiate an AuthenticationContext object. To this object, I
>> will set the current request, current response and initial request which is
>> the same as current request for the initial case. From the second request
>> for the ConditionalRequestCoordinator, only the current request and
>> response will be updated.
>>
>> In addition to the changes in the authentication framework, I have
>> implemented JavaScript wrapper classes for the HttpServletRequest and
>> HttpServletResponse Java classes in order to provide access to the
>> request/response state variables within JavaScript. Following are some
>> examples.
>>
>> *Request headers (context.request.headers)*
>>
>> context.request.headers.Authorization - this will give the value of the
>> Authorization header.
>>
>> *Request parameters (context.request.params)*
>>
>> context.request.params.redirect_uri - this will give the value of the
>> request parameter redirect_uri
>>
>> *Cookies in request (context.request.cookies)*
>>
>> context.cookies.commonAuthId - this will create a JavaScript wrapper for
>> the Cookie Java Class. We can access individual cookie attributes using
>> 

Re: [Architecture] [IS 5.5.0] Conditional steps based on HTTP context

2018-01-17 Thread Ruwan Abeykoon
Hi Sathya,

We can enhance the DefaultRequestCoordinator itself, rather than extending
and creating new coordinator, as there is no functional change done by
adding the "request" and "response" to authentication context.

Cheers,
Ruwan

On Wed, Jan 17, 2018 at 10:40 AM, Sathya Bandara  wrote:

> Hi all,
>
> We are currently working on improving the conditional authentication
> support using JavaScript feature [1] to be able to handle authentication
> conditions based on HTTP context.
>
> Following is the approach taken to achieve this requirement.
>
> In order to store the HTTP request and response I have modified the
> default AuthenticationContext class to have additional state variables for
> the authentication request and response(current request and response).
> These variables are declared as transient such that they will not be used
> for the object state at serialization. Furthermore, an additional variable
> will be used to keep a reference to the initial authentication request
> (initialRequest). When the second request comes, we will only update the
> current request and response variables.
>
> The DefaultRequestCoordinator will be replaced with
> ConditionalRequestCoordinator. In ConditionalRequestCordinator, inside
> initializeFlow() method which gets called for the initial authentication
> request, we instantiate an AuthenticationContext object. To this object, I
> will set the current request, current response and initial request which is
> the same as current request for the initial case. From the second request
> for the ConditionalRequestCoordinator, only the current request and
> response will be updated.
>
> In addition to the changes in the authentication framework, I have
> implemented JavaScript wrapper classes for the HttpServletRequest and
> HttpServletResponse Java classes in order to provide access to the
> request/response state variables within JavaScript. Following are some
> examples.
>
> *Request headers (context.request.headers)*
>
> context.request.headers.Authorization - this will give the value of the
> Authorization header.
>
> *Request parameters (context.request.params)*
>
> context.request.params.redirect_uri - this will give the value of the
> request parameter redirect_uri
>
> *Cookies in request (context.request.cookies)*
>
> context.cookies.commonAuthId - this will create a JavaScript wrapper for
> the Cookie Java Class. We can access individual cookie attributes using
> this wrapper as follows.
>
> context.request.cookies.commonAuthId.domain
> context.request.cookies.commonAuthId.value
>
> In request, we can only query existing attributes (headers and request
> parameters). cannot add or modify existing values.
>
> Similar approach was used for the HttpServletResponse class as well.
> However in HttpServletResponse, we have the capability to add new headers
> to the response.
>
> *Adding headers to the response*
>
> In order to wrap the setHeader() in JavaScript, I used the following
> implementation.
>
> public class JsHeaders extends AbstractJSObject {
>
> private Map wrapped;
> private HttpServletResponse response;
>
> public JsHeaders(Map wrapped, HttpServletResponse response) {
>
> this.wrapped = wrapped;
> this.response = response;
> }
>
> @Override
> public void setMember(String name, Object value) {
>
> if (wrapped == null) {
> super.setMember(name, value);
> } else {
> wrapped.put(name, value);
> response.setHeader(name, (String) value); //replaces the value
> if the name exists.
> }
> }
> }
>
> Here, I keep the existing headers in a map. Whenever
> context.response.headers is called , an instance of the JsHeaders wrapper
> is returned which contains the header map and a reference to the response.
> Once a new header is added as in example 
> context.response.headers.Authorization
> = "sample_value", the setMember() function is called. It will add the
> header (header name and value) to the referenced response.
>
> e.g. context.response.headers["Content-Type"] = 'application/json'
>
>
> *Adding cookies to the response *
>
> Similarly, when adding a new cookie to the response, we will add a new
> header to the response with the header name 'set-cookie'. This is similar
> to the approach used in nodejs [2].
>
> response.headers["set-cookie"] or response.headers.set-cookie can be used.
>
> An example would be as follows.
>
> response.headers.["Set-Cookie"] = ['crsftoken=xssometokenx',
> 'language=javascript']
>
> Highly appreciate your thoughts and suggestions.
>
> [1] [Architecture] Conditional Authentication Support on WSO2 Identity
> Server
> [2] https://nodejs.org/api/http.html#http_response_setheader_name_value
> 
>
> Thanks,
> Sathya
>
> --
> Sathya Bandara
> Software Engineer
> WSO2 Inc. http://wso2.com
> Mobile: (+94) 715 360 421 <+94%2071%20411%205032>
>
> 

[Architecture] [IS 5.5.0] Conditional steps based on HTTP context

2018-01-16 Thread Sathya Bandara
Hi all,

We are currently working on improving the conditional authentication
support using JavaScript feature [1] to be able to handle authentication
conditions based on HTTP context.

Following is the approach taken to achieve this requirement.

In order to store the HTTP request and response I have modified the default
AuthenticationContext class to have additional state variables for the
authentication request and response(current request and response). These
variables are declared as transient such that they will not be used for the
object state at serialization. Furthermore, an additional variable will be
used to keep a reference to the initial authentication request
(initialRequest). When the second request comes, we will only update the
current request and response variables.

The DefaultRequestCoordinator will be replaced with
ConditionalRequestCoordinator. In ConditionalRequestCordinator, inside
initializeFlow() method which gets called for the initial authentication
request, we instantiate an AuthenticationContext object. To this object, I
will set the current request, current response and initial request which is
the same as current request for the initial case. From the second request
for the ConditionalRequestCoordinator, only the current request and
response will be updated.

In addition to the changes in the authentication framework, I have
implemented JavaScript wrapper classes for the HttpServletRequest and
HttpServletResponse Java classes in order to provide access to the
request/response state variables within JavaScript. Following are some
examples.

*Request headers (context.request.headers)*

context.request.headers.Authorization - this will give the value of the
Authorization header.

*Request parameters (context.request.params)*

context.request.params.redirect_uri - this will give the value of the
request parameter redirect_uri

*Cookies in request (context.request.cookies)*

context.cookies.commonAuthId - this will create a JavaScript wrapper for
the Cookie Java Class. We can access individual cookie attributes using
this wrapper as follows.

context.request.cookies.commonAuthId.domain
context.request.cookies.commonAuthId.value

In request, we can only query existing attributes (headers and request
parameters). cannot add or modify existing values.

Similar approach was used for the HttpServletResponse class as well.
However in HttpServletResponse, we have the capability to add new headers
to the response.

*Adding headers to the response*

In order to wrap the setHeader() in JavaScript, I used the following
implementation.

public class JsHeaders extends AbstractJSObject {

private Map wrapped;
private HttpServletResponse response;

public JsHeaders(Map wrapped, HttpServletResponse response) {

this.wrapped = wrapped;
this.response = response;
}

@Override
public void setMember(String name, Object value) {

if (wrapped == null) {
super.setMember(name, value);
} else {
wrapped.put(name, value);
response.setHeader(name, (String) value); //replaces the value
if the name exists.
}
}
}

Here, I keep the existing headers in a map. Whenever
context.response.headers is called , an instance of the JsHeaders wrapper
is returned which contains the header map and a reference to the response.
Once a new header is added as in example context.response.headers.Authorization
= "sample_value", the setMember() function is called. It will add the
header (header name and value) to the referenced response.

e.g. context.response.headers["Content-Type"] = 'application/json'


*Adding cookies to the response *

Similarly, when adding a new cookie to the response, we will add a new
header to the response with the header name 'set-cookie'. This is similar
to the approach used in nodejs [2].

response.headers["set-cookie"] or response.headers.set-cookie can be used.

An example would be as follows.

response.headers.["Set-Cookie"] = ['crsftoken=xssometokenx',
'language=javascript']

Highly appreciate your thoughts and suggestions.

[1] [Architecture] Conditional Authentication Support on WSO2 Identity
Server
[2] https://nodejs.org/api/http.html#http_response_setheader_name_value


Thanks,
Sathya

-- 
Sathya Bandara
Software Engineer
WSO2 Inc. http://wso2.com
Mobile: (+94) 715 360 421 <+94%2071%20411%205032>

<+94%2071%20411%205032>
___
Architecture mailing list
Architecture@wso2.org
https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture