MVC3 + WIF - FederationResult missing "wctx" - asp.net-mvc-3

I have an MVC3 app for which I want to implement claims support. My goal is as follows:
provide a SignIn link, which when clicked displays a popup window with username/password and Facebook/WindowsLive/Google etc. links
automatically redirect to my SignIn page when a protected controller is accessed e.g. /Order/Delete
I've set up the application and providers in AppFabricLabs.com and included the STS in my project. I've also created an implementation of IAuthorizationFilter so I can mark my controllers as [WifAuth] and successfully get the OnAuthorization method called. I've implemented the use-case where the visitor has not been authenticated like this:
private static void AuthenticateUser(AuthorizationContext context)
{
var fam = FederatedAuthentication.WSFederationAuthenticationModule;
var signIn = new SignInRequestMessage(new Uri(fam.Issuer), fam.Realm);
context.Result = new RedirectResult(signIn.WriteQueryString());
}
and successfully get AppFabricLabs page with my Identity Provider choices (haven't figured out how to customise that page). When I log in my returnUrl gets called so I land in a controller method /Home/FederationResult, however the form posted to me contains only wa and wresult fields but I need wctx to know where to send the user... I haven't been able to figure out why.
the wresult is an XML document that contains (amongst a bzillion other things) the name and e-mail address of the user logging in but sadly does not contain the url to which the user was headed.
have I failed to configure something or am I just off base? thoughts anyone?
e

Just specify a Context for the SignInRequestMessage:
signIn.Context = HttpContext.Current.Request.RawUrl;
The wctx parameter is included in every request/response and also part of the form posted finally to your site.

Related

ASP.NET Core 6 non Default Identity UI based Authentication with email/sms based TFA

I have to port a website which has a TFA authentication via sms/email to asp.net 6. The client doesn’t want to use an authenticator app. The application has some specialities such as the language of the user in the URL path as the first component.
In this post I searched a way to introduce the language part and was, although in a very ugly manner, successful.
However I'm also quite unhappy to use the default UI in general for this application, since I have to manually deactivate all the things that are not required but are included in the library. It feels extremely untidy to have such a huge framework of pages active for so little of required functionality. The only things I need are
Login with a username and password
Optionally checking a tfa email/sms code if the user has configured its account for this.
The configuration of the user's profile is done in another application and should not be included in this application (hence all the default identity ui stuff has to be deactivated).
I tried to create the authentication logic manually via controller actions and not installing the default ui at all. For the login with username and password, this was fairly easy.
However, setting up the TFA part seems quite tedious and dangerous (from a security perspective). I have not found any documentation what resources have to be registered and how to setup the authentication system.
Is searching out all the required dependencies and creating the code from the Microsoft source code of default identity UI the only way?
Or is there a template solution to accomplish the desired goal?
Since there seems no such information available, I gathered the necessary code from the ms source code. Maybe it helps someone:
Registration
Copied out of the ms source code, here the required registrations:
builder.Services.AddIdentityCore<MyUserType>().AddDefaultTokenProviders();
builder.Services.TryAddScoped<ITwoFactorSecurityStampValidator, TwoFactorSecurityStampValidator<MyUserType>>();
builder.Services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<MyUserType>>();
builder.Services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
// options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddCookie(IdentityConstants.ApplicationScheme, o =>
{
o.LoginPath = [your login path];
o.LogoutPath = [your logout path];
})
//.AddCookie(IdentityConstants.ExternalScheme, o =>
//{
// o.Cookie.Name = IdentityConstants.ExternalScheme;
// o.ExpireTimeSpan = TimeSpan.FromMinutes(5);
//})
.AddCookie(IdentityConstants.TwoFactorRememberMeScheme, o =>
{
o.Cookie.Name = IdentityConstants.TwoFactorRememberMeScheme;
o.Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = SecurityStampValidator.ValidateAsync<ITwoFactorSecurityStampValidator>
};
})
.AddCookie(IdentityConstants.TwoFactorUserIdScheme, o =>
{
o.Cookie.Name = IdentityConstants.TwoFactorUserIdScheme;
o.ExpireTimeSpan = TimeSpan.FromMinutes(5);
});
The registration for the external authentication is commented out, maybe someone wants to use that also, therefore i have not directly removed it from the code. The login path can be set accordingly to your login-action. See my other post about how to extend the login url to introduce language and other path components.
Controller-code
The controller's action code and views can then derived from the original default identity ui code. The AddDefaultTokenProviders call is required to have the email token provider registered.
Result
In this way, the default ui and all its abundant functionality is no more in the project and one can selectively decide, what parts to integrate.

Kentico Tapping into Page Level Events

We are creating webevents in a DB other than Kentico. These webevents are then used for enterprise reporting. I need to implement the same inside Kentico project.
Is there an event that can fire after the page has loaded so that i can create my web event with page name and user information if logged in.
I have also seen in the past that with events, the Request and Session objects are not available. However, HTTPContext.Current is available. I need the Request and Session objects.
We are using Kentico version 7.0.92 and have a portal template site.
Now, i don't want to use portal template page to create events since this code executes multiple times with each request for a page.
Basically, i am interested in the PageName, Session and Request objects.
I have looked around Kentico 7 documentation. Looks like we have CMSRequestEvents but haven't been able to find sample code.
Update:
Looks like the missing piece is CMSContext class. Now just trying to find the right event for CMSRequestEvents, where i have the Session object available.
I'd suggest modifying Kentico\CMS\Global.asax.cs in the following way:
public override void Init()
{
base.Init();
CMSRequestEvents.AcquireRequestState.After += AcquireRequestState_After;
}
void AcquireRequestState_After(object sender, EventArgs e)
{
// Do your stuff...
}
By that time the HttpContext.Current.Session should already be initialized. Page name can be retrieved from the HttpContext.Current.Request which should never be null.

Google Drive SDK 1.8.1 RedirectURL

Is there any way to provide RedirectURL then using GoogleWebAuthorizationBroker?
Here is the sample code in C#:
Task<UserCredential> credential = GoogleWebAuthorizationBroker.AuthorizeAsync(secrets, scopes, GoogleDataStore.User, cancellationToken, dataStore);
Or we have to use different approach?
I have an "installed application" that runs on a user's desktop, not a website. By default, when I create an "installed application" project in the API console, the redirect URI seems to be set to local host by default.
What ends up happening is that after the authentication sequence the user gets redirected to localhost and receives a browser error. I would like to prevent this from happening by providing my own redirect URI: urn:ietf:wg:oauth:2.0:oob:auto
This seems to be possible using Python version of the Google Client API, but I find it difficult to find any reference to this with .NET.
Take a look in the implementation of PromptCodeReceiver, as you can see it contains the redirect uri.
You can implement your own ICodeReceiver with your prefer redirect uri, and call it from a WebBroker which should be similar to GoogleWebAuthorizationBroker.
I think it would be great to understand why can't you just use PrompotCodeReceiver or LocalServerCodeReceiver.
And be aware that we just released a new library last week, so you should update it to 1.9.0.
UPDATE (more details, Nov 25th 2014):
You can create your own ICodeReceiver. You will have to do the following:
* The code was never tested... sorry.
public class MyNewCodeReceiver : ICodeReceiver
{
public string RedirectUri
{
get { return YOU_REDIRECT_URI; }
}
public Task<AuthorizationCodeResponseUrl> ReceiveCodeAsync(
AuthorizationCodeRequestUrl url,
CancellationToken taskCancellationToken)
{
// YOUR CODE HERE FOR RECEIVING CODE FROM THE URL.
// TAKE A LOOK AT THE FOLLOWING:
// PromptCodeReceiver AND LocalServerCodeReceiver
// FOR EXAMPLES.
}
}
PromptCodeReceiver
and LocalServerCodeReceiver.
Then you will have to do the following
(instead of using the GoogleWebAuthorizationBroker.AuthorizeAsync method):
var initializer = new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = secrets,
Scopes = scopes,
DataStore = new FileDataStore("Google.Apis.Auth");
};
await new AuthorizationCodeInstalledApp(
new GoogleAuthorizationCodeFlow(initializer),
new MyNewCodeReceiver())
.AuthorizeAsync(user, taskCancellationToken);
In addition:
I'll be happy to understand further why you need to set a different redirect uri, so we will be able to improve the library accordingly.
When I create an installed application the current PromptCodeReceiver and LocalServerCodeReceiver work for me, so I'm not sure what's the problem with your code.

Is it possible to specify the page navigation using some properties kind of file in spring MVC like in JSF?

I am building a website using spring mvc. Just I built the login screen and the related controllers and services.
Now when validating the user credentials if the given password is wrong then it should navigate back to the login.jsp page. If the inputs are correct then it should navigate to userHomepage.jsp page.
I have done this as below,
try {
loginService.checkUserValidity(userId, password);
return new ModelAndView("userHomePage"); //if all the user credentials are good then redirect the user to User Home Page
} catch (UserNotExistsException e) {
loginResult = e.toString();
return new ModelAndView("login", "loginResult", loginResult);
} catch (InvalidPasswordException e) {
loginResult = e.toString();
return new ModelAndView("login", "loginResult", loginResult);
}
In the above code snippet I was hardcoding the navigating pages file names in ModelAndView (like login, userHomePage etc.,).
Is it correct approach to hardcode them? Is it possible to specify the page navigation using some properties kind of file in spring MVC like in JSF? Is spring MVC webflow sole purpose that?
Thanks
It's not unusual to hae the views specified as you have them.
If you have complex navigation you wanr to specify in an XML file, like JSF, Spring Webflow is for you. It can be tricky to set up, but provides a nice framework for complex navigation.
Have you set up Spring Security? The user is sent to the login page (form) when he's unauthorised, otherwise to the page he requested.

Setting roles by using GenericPrincipal instance

Recently I asked a question about how to use ajax calls to
authenticate user in asp.net mvc, and I got my answer.
But then is decided to use 'Roles' property of 'GenericPrincipal' class
so I changed my code as follow to contain 'Roles':
HttpContext.User = new System.Security.Principal.
GenericPrincipal(new System.Security.Principal.GenericIdentity(login.LoginName),
userRole);
In my site.master view, I check to see which kind of roles users
belongs to and I show appropriate menu, but when I watch
'HttpContext.Current.User.Identity' values during debugging,
I see m_roles=string[0] and 'IsInRole("Admin")' returns false.
How could it be fixed?
Try setting the current thread principle:
System.Threading.Thread.CurrentPrincipal = principal;
as is shown here:
http://social.msdn.microsoft.com/forums/en-US/Vsexpressvcs/thread/5f9735a9-096b-47af-963d-e95130cad6b4

Resources