Reputation: 35572
Here is my Scenario.
I have authentication web-services exposed by another domain. Now I want user name and password to be sent to that external domain for authentication. and when user is authenticated (returned true
), I want the ASP.net to take that authentication further and let the user in and provide me all the asp.net standard utilities accessible, like currentuser, Isauthorized, Roles etc, for the user, authenticated. I hope this make sense.
Upvotes: 0
Views: 1964
Reputation: 873
You can you use Security Token Service for your application. Setup a Windows Identity Foundation SDK and find examples in sdk directory (for me it is "C:\Program Files (x86)\Windows Identity Foundation SDK\v4.0\Samples\End-to-end\Federation for Web Apps"). One of them ( named "Federation for Web Apps") implement your case for AD authentication.
Upvotes: 0
Reputation: 42497
This is not a problem. You have a variety of options available to you. One approach is to blend Forms Authentication with your own security model.
The basic idea is to let Forms Auth create and manage a ticket (in the form of an encrypted ticket) for the logged-in user. The ticket is used to determine whether or not someone is logged in, and who they are. You can then mix in any additional security related logic on top of that.
To process the login request, you just have a controller and action like you normally would. Note: in the example below, I am making some assumptions about LoginViewModel
, the service you are using to authenticate, and the object it returns if any. You'll have to sub in your actual logic.
public ActionResult Login(LoginViewModel model)
{
// make sure the user filled out the login fields correctly
if (!ModelState.IsValid) return View(model);
// authenticate the user here
var authenticatedUser = AuthorizeUserUsingRemoteWebService(model.Username, model.Password);
if (authenticatedUser.IsAuthenticated)
{
// create forms auth ticket cookie and redirect to the home page
FormsAuthentication.SetAuthCookie(authenticatedUser.Username);
return RedirectToAction("Index", "Home");
}
// authentication failed, so show the login page again
return View(model);
}
In addition to that, you may have an HTTP module that handles the AuthenticateRequest event. Your module will be registered after the Forms Auth HTTP module, so it will have already processed whether or not the user is logged in. What you want to do is look up additional information if they are logged in, to get roles and such.
public class CustomAuthHttpModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.AuthenticateRequest += new EventHandler(OnAuthenticateRequest);
}
void OnAuthenticateRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = appObject.Context;
// user isn't logged in, so don't do anything else
if (!context.User.Identity.IsAuthenticated) return;
// look up the roles for the specified user, returning the role names as an array of strings
string[] roles = LookupUserRolesFromWebService(context.User.Identity.Name);
// replace the current User principal with a new one that includes the roles we discovered for that user.
context.User = new GenericPrincipal(new GenericIdentity(context.User.Identity.Name), roles);
}
}
You'll register the HTTP module in your web.config:
<httpModules>
<add name="CustomAuthHttpModule"
type="MyAssembly.CustomAuthenticationModule, MyAssembly" />
</httpModules>
You can now use the User object in your MVC controllers and views, the AuthenticatedAttribute
, etc.
However, I'd recommend that you cache the results of looking up a user's roles so you don't hammer your web service. I'll leave that up to you.
Upvotes: 2