|
//------------------------------------------------------------------------------
// <copyright file="PassportAuthenticationModule.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
/*
* PassportAuthenticationModule class
*
* Copyright (c) 1999 Microsoft Corporation
*/
namespace System.Web.Security {
using System.Web;
using System.Security.Principal;
using System.Web.Configuration;
using System.Web.Handlers;
using System.Globalization;
using System.Security.Permissions;
using System.Web.Management;
/// <devdoc>
/// This
/// module provides a wrapper around passport authentication services.
/// </devdoc>
[Obsolete("This type is obsolete. The Passport authentication product is no longer supported and has been superseded by Live ID.")]
public sealed class PassportAuthenticationModule : IHttpModule {
private PassportAuthenticationEventHandler _eventHandler;
private static bool _fAuthChecked = false;
private static bool _fAuthRequired = false;
private static String _LoginUrl = null;
/// <devdoc>
/// <para>
/// Initializes a new instance of the <see cref='System.Web.Security.PassportAuthenticationModule'/>
/// class.
/// </para>
/// </devdoc>
[SecurityPermission(SecurityAction.Demand, Unrestricted=true)]
public PassportAuthenticationModule() {
}
////////////////////////////////////////////////////////////
// AddOnAuthenticate and RemoveOnAuthenticate: Use these
// methods to hook up event handlers to handle the
// OnAuthenticate Event
/// <devdoc>
/// This is a global.asax event that must be
/// named PassportAuthenticate_OnAuthenticate event.
/// </devdoc>
public event PassportAuthenticationEventHandler Authenticate {
add {
_eventHandler += value;
}
remove {
_eventHandler -= value;
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public void Dispose() {
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public void Init(HttpApplication app) {
app.AuthenticateRequest += new EventHandler(this.OnEnter);
app.EndRequest += new EventHandler(this.OnLeave);
}
////////////////////////////////////////////////////////////
// OnAuthenticate: Custom Authentication modules can override
// this method to create a custom IPrincipal object from
// a PassportIdentity
/// <devdoc>
/// Calls the
/// PassportAuthentication_OnAuthenticate handler, if one exists.
/// </devdoc>
void OnAuthenticate(PassportAuthenticationEventArgs e) {
////////////////////////////////////////////////////////////
// If there are event handlers, invoke the handlers
if (_eventHandler != null) {
_eventHandler(this, e);
if (e.Context.User == null && e.User != null)
{
InternalSecurityPermissions.ControlPrincipal.Demand();
e.Context.User = e.User;
}
}
////////////////////////////////////////////////////////////
// Default Implementation: If IPrincipal has not been created,
// create a PassportUser
if (e.Context.User == null)
{
InternalSecurityPermissions.ControlPrincipal.Demand();
e.Context.User = new PassportPrincipal(e.Identity, new String[0]);
}
}
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Methods for internal implementation
/// <internalonly/>
/// <devdoc>
/// </devdoc>
void OnEnter(Object source, EventArgs eventArgs) {
if (_fAuthChecked && !_fAuthRequired)
return;
HttpApplication app;
HttpContext context;
app = (HttpApplication)source;
context = app.Context;
if (!_fAuthChecked) {
AuthenticationSection settings = RuntimeConfig.GetAppConfig().Authentication;
_fAuthRequired = (AuthenticationConfig.Mode == AuthenticationMode.Passport);
_LoginUrl = settings.Passport.RedirectUrl;
_fAuthChecked = true;
}
if (!_fAuthRequired)
return;
////////////////////////////////////////////////////////
// Step 1: See if this request is valid or not
// VSWhidbey 442515: We no longer need to do this check, always proceed
////////////////////////////////////////////////////////
// Step 2: Create a Passport Identity from the credentials
// from IIS
PassportIdentity identity = new PassportIdentity();
////////////////////////////////////////////////////////
// Step 4: Call OnAuthenticate virtual method to create
// an IPrincipal for this request
OnAuthenticate( new PassportAuthenticationEventArgs(identity, context) );
////////////////////////////////////////////////////////
// Skip AuthZ if accessing the login page
context.SetSkipAuthorizationNoDemand(AuthenticationConfig.AccessingLoginPage(context, _LoginUrl), false /*managedOnly*/);
if (!context.SkipAuthorization) {
context.SkipAuthorization = AssemblyResourceLoader.IsValidWebResourceRequest(context);
}
}
void OnLeave(Object source, EventArgs eventArgs) {
HttpApplication app;
HttpContext context;
app = (HttpApplication)source;
context = app.Context;
if (!_fAuthChecked || !_fAuthRequired || context.User == null || context.User.Identity == null || !(context.User.Identity is PassportIdentity))
return;
PassportIdentity id = (PassportIdentity) context.User.Identity;
if (context.Response.StatusCode != 401 || id.WWWAuthHeaderSet)
return;
if ( _LoginUrl==null || _LoginUrl.Length < 1 || String.Compare(_LoginUrl, "internal", StringComparison.Ordinal) == 0) {
context.Response.Clear();
context.Response.StatusCode = 200;
if (!ErrorFormatter.RequiresAdaptiveErrorReporting(context)) {
String strUrl = context.Request.Url.ToString();
int iPos = strUrl.IndexOf('?');
if (iPos >= 0) {
strUrl = strUrl.Substring(0, iPos);
}
String strLogoTag = id.LogoTag2(HttpUtility.UrlEncode(strUrl, context.Request.ContentEncoding));
String strMsg = SR.GetString(SR.PassportAuthFailed, strLogoTag);
context.Response.Write(strMsg);
}
else {
ErrorFormatter errorFormatter = new PassportAuthFailedErrorFormatter();
context.Response.Write(errorFormatter.GetAdaptiveErrorMessage(context, true));
}
}
else {
////////////////////////////////////////////////////////////
// Step 1: Get the redirect url
String redirectUrl = AuthenticationConfig.GetCompleteLoginUrl(context, _LoginUrl);
////////////////////////////////////////////////////////////
// Step 2: Check if we have a valid url to the redirect-page
if (redirectUrl == null || redirectUrl.Length <= 0)
throw new HttpException(SR.GetString(SR.Invalid_Passport_Redirect_URL));
////////////////////////////////////////////////////////////
// Step 3: Construct the redirect-to url
String strUrl = context.Request.Url.ToString();
String strRedirect;
int iIndex;
String strSep;
if (redirectUrl.IndexOf('?') >= 0)
strSep = "&";
else
strSep = "?";
strRedirect = redirectUrl + strSep + "ReturnUrl=" + HttpUtility.UrlEncode(strUrl, context.Request.ContentEncoding);
////////////////////////////////////////////////////////////
// Step 4: Add the query-string from the current url
iIndex = strUrl.IndexOf('?');
if (iIndex >= 0 && iIndex < strUrl.Length-1)
strRedirect += "&" + strUrl.Substring(iIndex+1);
////////////////////////////////////////////////////////////
// Step 5: Do the redirect
context.Response.Redirect(strRedirect, false);
}
}
}
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
// ErrorFormatter for generating adaptive error for mobile devices
internal class PassportAuthFailedErrorFormatter : ErrorFormatter {
protected override string ErrorTitle {
get { return SR.GetString(SR.PassportAuthFailed_Title);}
}
protected override string Description {
get { return SR.GetString(SR.PassportAuthFailed_Description);}
}
protected override string MiscSectionTitle {
get { return SR.GetString(SR.Assess_Denied_Title);}
}
protected override string MiscSectionContent {
get { return null;}
}
protected override string ColoredSquareTitle {
get { return null;}
}
protected override string ColoredSquareContent {
get { return null;}
}
protected override bool ShowSourceFileInfo {
get { return false;}
}
}
}
|