Identity Server 3 multiple LogoutUris for same client - asp.net-mvc

I have an MVC application which is multi tenant, differentiated by domain name:
app.tenant1.com
app.tenant2.com
And I have a single Client in IdentityServer (hybrid flow) with
with
RedirectUris = [http://app.tenant1.com, http://app.tenant2.com]
PostLogoutRedirectUris = [http://app.tenant1.com, http://app.tenant2.com]
But Logout uri only allows for a string value, not a list of strings
LogoutUri = "http://app.tenant1.com/home/SignoutCleanup";
My problem is that when I singout from app.tenant2.com I want the LogoutUri to be "http://app.tenant2.com/home/signoutcleanup"
Is there a way of doing this?
Thanks
PS: Is there a way to pass data to IS3 in the SingoutMessage? Similar to how we pass data in the acr_values ?
PPS: I've implemented a CustomEventService and log the user logins. Is there also a way of logging the Log out events ?
Thanks :)
EDIT:
I see that this is the url that's called in order to generate the iframes which in turn call the signout for all apps
/core/connect/endsessioncallback
Is there a way to intercept this url and make changes to it's response?

Given the limitation of cookies being scoped to hostnames, you could change how you configure this client to be multiple clients instead. The other idea is to use a host-level cookie to keep track of the tenant, and then use host-level signout cleanup URL.

Related

C# MsGraph-SDK: Send a BatchRequest to get manager links using Microsoft Graph SDK

First of all please share if there is any MSGraph SDK official documentation anywhere that I can use for reference.
I have a scenario, where I want to query all manager and member links from AAD without providing the user and group objectID respectively. This is currently supported in DQ channel, i.e. I can do something like this using MsGraphSDK:
MsGraphClient.Users.Delta().Request().Select("manager")
OR
MsGraphClient.Groups.Delta().Request().Select("members")
I don't want to use DQ for initial-sync due to performance problems, and other issues.
My fallback option is to query through Graph directly, so I want to do something like the following, but this doesn't return any result:
MsGraphClient.Users.Request().Select("manager")
OR
MsGraphClient.Groups.Request().Select("members")
It looks like this isn't even supported currently at the lower (AADGraph) layer. Please correct me if I am wrong, and provide a solution if any!
So my fallback approach is to pull all the user and group aadObjectIds, and explicitly query the manager and member links respectively.
In my case, there can potentially be 500K User-Objects in AAD, and I want to avoid making 500K separate GetManager calls to AAD. Instead, I want to batch the Graph requests as much as possible.
I wasn't able to find much help from the Internet on sending Batch requests through SDK.
Here's what I am doing:
I have this BatchRequestContent:
var batchRequestContent = new BatchRequestContent();
foreach (string aadObjectId in aadObjectIds)
{
batchRequestContent.AddBatchRequestStep(new BatchRequestStep(aadObjectId, Client.Users[aadObjectId].Manager.Request().GetHttpRequestMessage()));
}
and I am trying to send a BatchRequest through GraphSDK with this content to get a BatchResponse. Is this currently supported in SDK? If yes, then what's the procedure? Any documentation or example? How to read the batch-response back? Finally, is there any limit for the # of requests in a batch?
Thanks,
Here is a related post: $expand=manager does not expand manager
$expand is currently not supported on the manager and directReports relationships in the v1.0 endpoint. It is support in the beta endpoint but
the API returns way to much throw away information: https://graph.microsoft.com/beta/users?$expand=manager
The client library partially supports Batch at this time although we have a couple of pull requests to provide better support
with the next release (PR 1 and 2).
To use batch with the current library and your authenticated client, you'll do something like this:
var authProv = MsGraphClient.AuthenticationProvider;
var httpClient = GraphClientFactory.Create(authProv);
// Send batch request with BatchRequestContent.
HttpResponseMessage response = await httpClient.PostAsync("https://graph.microsoft.com/v1.0/$batch", batchRequestContent);
// Handle http responses using BatchResponseContent.
BatchResponseContent batchResponseContent = new BatchResponseContent(response);

Is it possible to resolve navigation outcome in order to validate it?

I've got a WebFilter that redirects to the login page in my application. In order to redirect back to the referring page I've also added a view parameter called redirectOnLogin which is then used on successful logins in order to perform the final navigation.
If one were to manipulate this query parameter, one could easily provoke JSF navigation errors. I would therefore like to pre-empt this by checking that the outcome is valid but I've not been able to uncover a mechanism for pre-validating a JSF outcome.
Easiest and best is to make sure the redirectToLogin parameter cannot be manipulated. Or that manipulation is detected.
You could solve this in (at least) two ways
Taking the original page name, adding a 'salt' to it and creating a hash.
Addin this has that in the request to the login server
Make sure it is returned by the login server (maybe adding it as # to the return page or as a param.
On receiving it on the 'redirectOnLogin' page, use the page name, the same salt and create a hash in the same way. Compare these and if they match you are fine, if they don't throw an error.
Or you could
Store the 'redirectOnLogin' page in a session to
Check on returning from the login server if it matches with the page you end-up on.

how to have per-session token value in struts2

How can we have persistent token value(or Form Key) during the valid session in struts2?
When <s:token/> is in the forms, after submitting the form, the token's value gets changed. It causes this problem that users can not open 2 browser tab and work with them(Only one tab is active due to the tokens' unique value per form).
how can I solve this with struts2 and have durable token value per session(Not per form)?
I think overriding the interceptor can solve the problem, but i wanna
to consider other options
Don't use token at all
If you require something per session, use the session itself. Token is meant to prevent request replay attacks. So just having one per session doesn't make sense.
I also had same problem, in my functionality there is preview which opens in new tab. User can preview multiple times, so it was throwing a token exception. I got one code as at start of function I wrote :
String downloadTokenName = TokenHelper.getTokenName();
String downloadToken = TokenHelper.getToken(downloadTokenName);
At end of function in finally I reassign token value as :
TokenHelper.setSessionToken(downloadTokenName, downloadToken);
It solved my problem.

Error configuring the requestmap in spring security core for grails

In my system, I have numerous roles assigned to the users (lets assume 3 for now ROLE_ADMIN, ROLE_USER, ROLE_SERVICES). In one of my controllers (lets assume SearchController that we have three actions serviceIndex{}, userIndex{} and adminIndex{}), I want users of any role to be able to access two of the actions (the first two). For the final action, I want to restrict the action against a user of single role type (lets say ROLE_USER) but allow access to users of other roles (i.e. to ROLE_ADMIN, ROLE_SERVICE. I have something like the following in my requestmap table.
config_attribute ----------------------------------------------------------->url
ROLE_ADMIN,ROLE_SERVICE,ROLE_USER ------------------------------> /search/serviceIndex
ROLE_ADMIN,ROLE_SERVICE,ROLE_USER-------------------------------> /search/userIndex
ROLE_ADMIN,ROLE_SERVICE -----------------------------------------> /search/adminIndex
Since the third rule states that the url '/search/adminIndex' is not accessible to ROLE_USER, the user with that role should have been denied the authorization to access the url. But, the user can still access the url. What is the correct configuration. I did try someting like /search/adminIndex/**, but that doesn't work either. On a side note, none of the urls will have suffixes furthermore but I would still like to prevent access if users manipulate the url like adding suffixes like /search/userIndex/56a just in case.
Regards,
dipess
Since the plugin iterates through the rules and applies the first one that matches the current URL, I would set the adminIndex first and then have a catchall for anything else.
ROLE_ADMIN,ROLE_SERVICE /search/adminIndex
ROLE_ADMIN,ROLE_SERVICE,ROLE_USER /search/**

Store cookie even if the session is closed

What would be the best approach for a Play! application to remember the user? I think the only possible solution is to use the client side cookies, right? But as soon as the browser shuts down, this session is destroyed and not valid for the next request? How did/do you solve(d) this?
As for now, I ser the crypted userid in the session (per session), like this:
session("userid", user.id);
And then I use the interceptor to avoid passing parameters every when I need them oft, like described here: How to avoid passing parameters everywhere in play2?
But how to remember the user, or even beter, automatically log the user in on the next request?
EDIT: 2016-03-11
Be aware that some browser may store the session cookie for a longer period. For instance you can set in Chrome to remember the open tabs on next visit. This means that the Play Session cookie will be restored next time you open the browser.
And as of Play 2.4 the session cookie maxAge (you need to set in the application.conf) is renamed to: play.http.session.maxAge
To make the session not time-out when a users closes their browser you can use the session.maxAge parameter in the application.conf.
e.g.:
# Set session maximum age in seconds (4w)
session.maxAge=2419200
Quoting from Play 2.0 Session Documentation:
There is no technical timeout for the Session. It expires when the user closes the web browser. If you need a functional timeout for a specific application, just store a timestamp into the user Session and use it however your application needs (e.g. for a maximum session duration, maxmimum inactivity duration, etc.).
For security reasons, modern browsers will invalidate cookies on exit, and this is not something you can change simply because it would allow hackers to bad things with credentials that they do not rightfully have.
I would reevalutate whether or not you truly want the user to stay logged in, since it is usually a security risk to do so. If, however, you decide that you still want the user to stay logged in, you will have to try something that is not cookie based, and at the moment, I'm not sure what that would look like.
If you don't force a newSession or the user doesn't remove the cookies, the user should still be logged in.
It may be that your browser is set up to remove cookies when closing, or you are suffering from an external sideeffect. But I can confirm that cookies persist in my dev environment (in both Chrome and Firefox) after closing the browser.
I tried this and it worked for me. It's basically a composed Action.
def RememberAction(f: Request[AnyContent] => Result): Action[AnyContent] = {
Action { request =>
if(!request.session.get("email").isDefined && request.cookies.get("remember-email").isDefined) {
f(request).asInstanceOf[PlainResult].withSession("email" -> request.cookies.get("remember-email").get.value)
} else {
f(request)
}
}
}
Then you can use this Action in your controllers like this:
def index = RememberAction { implicit request =>
Ok("Hello World!")
}

Resources