Benutzer:MovGP0/NET/WIF

 MovGP0   Über mich   Hilfen   Artikel   Weblinks   Literatur   Zitate   Notizen   Programmierung   MSCert   Physik 


Ticket/Token Formats

  • FormsAuthenticationTicket
  • JWT Tokens
    • JSON basiert; Binär- und XML-Serialisierung möglich
    • unterstützt Claims, Signatur, Verschlüsselung
    • Standard bei OAuth
  • SAML Token
    • unterstützt Claims, Signatur, Verschlüsselung
    • SAML-Protokoll wird in WIF nicht unterstützt; es kommen WS-* Protokolle zur Anwendung
    • komplexer Standard. der Stack muss XML Signaturen, XML Verschlüsselung, SOAP, etc. können
  • X.509 Certificate Token
  • Kerberos Ticket
  • etc.

Wichtige Protokolle

Konfiguration von web.config

Simple configurations can be done using the Federation Utility Wizard (FedUtil.exe). Add STS Reference (STS = Security Token Service) in Visual Studio when WIF SDK is installed.

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="microsoft.identityModel" type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection,Microsoft.IdentityModel,Version=3.5.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35" />
        <!-- ... -->
    </configSections>

    <appSettings>
        <add key="FederationMetadataLocation" value="./FederationMetadata.xml">
    </appSettings>

    <system.web>
        <authentication mode="None" />
        <authorization>
            <deny users="?" /><!-- '?' = not authenticated users; '*' = all users  -->
        <authorization>
        <!-- configure access for directiories based on roles here -->
    </system.web>

    <!-- use <httpModules> if IIS version < 7.0 -->
    <system.webServer> 
        <validation validateIntegratedModeConfiguration="false" />
        
        <modules>
            <!-- authenticate user with external token service -->
            <!-- it's events are handeled in global.asax -->
            <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule,Microsoft.IdentityModel,Version=3.5.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" />

            <!-- already authenticated sessions -->
            <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule,Microsoft.IdentityModel,Version=3.5.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" />

            <!-- checks if user is authorized to access a given resource given his claims -->
            <add name="ClaimsAuthorizationModule" type="Microsoft.IdentityModel.Web.ClaimsAuthorizationModule,,Microsoft.IdentityModel,Version=3.5.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" />
        </modules>
    </system.webServer>

    <!-- configuration for WIF plugins -->
    <microsoft.identityModel>
        <service>
            <!-- configure how to validate tokens -->
            <audienceUris>
                <add value="https://my-sitename/">
            </audienceUris>
            <certificateValidation>
                <certificateValidator ... />
            </certificateValidation>
            
            <!-- supported are 
                * Samt11SecurityTokenHandler, 
                * Saml2SecurityTokenHandler, 
                * X509SecrityTokenHandler, 
                * KerberosSecurityTokenHandler, 
                * WindowsUserNameSecurityTokenHandler, 
                * RsaSecurityTokenHandler, 
                * EncryptedSecurityTokenHandler 
            -->
            <securityTokenHandlers>
                <securityTokenHandlerConfiguration>
                    <!-- concrete configuration depends on handler -->
                    <tokenReplayDetection ... />
                </securityTokenHandlerConfiguration>
            </securityTokenHandlers>
            
            <!-- authentication with external WS-* provider -->
            <federatedAuthentication> 
                <wsFederation passiveRedirectEnabled="true" issuer="https://my-STS-provider.com" realm="https://my-sitename/" requireHttps="true" /> <!-- has many more configuration attributes -->
                <cookieHandler requireHttps="true" />
                <!-- <maximunClockSkew ... /> -->
                <!-- <serviceCertificate ... /> -->
            </federatedAuthentication>
            
            <!-- claims whick the application needs about the user -->
            <applicationService>
                <claimTypeReqired>
                    <claim type="http://schemas.xmlsoap.org/claims/Group" optionalt="true" />
                    <claim type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" optionalt="true" />
                </claimTypeReqired>
            <applicationService>
            
            <!-- thumbprint of the WS-* provider  -->
            <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry,,Microsoft.IdentityModel,Version=3.5.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35">
                <trustedIssuers>
                    <add thumbprint="OE2A9EB75F1AFC321790407FA4B130E0E4E22" name="https://my-STS-provider.com" />
                </trustedIssuers>
            </issuerNameRegistry>
            
            <!-- custom authorization manager -->
            <claimsAuthorizationManager type="MyNamespace.AgeTreshholdClaimsAuthorizationManager">
                <policy resource="/xxx.gif" action="GET">
                    <claim claimType="http://schemas.xmlsoap.org/ws/2005-05-identity/claims/dateofbirth" minAge="21" />
                </policy>
            </claimsAuthorizationManager>
        </service>
    </microsoft.identityModel>

    <assemblies>
        <add assembly="Microsoft.IdentityModel,Version=3.5.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35">
    </assemblies>
</configuration>

Handling Identities with Claims

  • IClaimsPrincipal : IPrincipal
  • IClaimsIdentity : IIdentity
  • Claim
IClaimsIdentity = Thread.CurrentPrincipal.Identity as IClaimsIdentity;
var email = identity.Claims.Where(c => c.ClaimType == System.IdentityModel.Claims.ClaimTypes.Email).FirstOrDefault();

Custom ClaimsAuthorizationManager

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Configuration;
using System.Xml;
using Microsoft.IdentityModel.Claims;
using Microsoft.IdentityModel.Configuration;

namespace MyNamespace
{
    public sealed class AgeTreshholdClaimsAuthorizationManager : ClaimsAuthorizationManager
    {
        private static Dictionary<string, int> Policies { get; } = new Dictionary<string, int>();
        
        public AgeTreshholdClaimsAuthorizationManager(object config)
        {
            var nodes = config as XmlNodeList;
            foreach(var node in nodes)
            {
                var reader = XmlTextReader(new StringReader(node.OuterXml));
                reader.MoveToContent();
                var resource = reader.GetAttribute("resource");
                reader.Read();
                var claimType = reader.GetAttribute("claimType");
                
                if(claimType.Equals(ClaimTypes.DateOfBirth, StringComparison.Ordinal))
                {
                    throw new NotSupportedException();
                }
                
                var minAge = reader.GetAttribute("minAge");
                Policies[resource] = int.Parse(minAge);
            }
        }
        
        public override bool CheckAccess(AuthorizationContext context)
        {
            Uri webPage = new Uri(context.Resource.First().Value);
            
            if(!Policies.ContainsKey(webPage.PathAndQuery))
            {
                return true; // resource is not age protecdet
            }
            
            IClaimsIdentity claimsIdentity = context.HttpContext.User.Identity as IClaimsIdentity;
            
            var minAge = Policies[webPage.PathAndQuery];
            var birthday = DateTime.Parse(claimsIdentity.Claims.Where(c => c.ClaimType == ClaimTypes.DateOfBirth).Select(c => c.Value));
            
            return dateTime.Today >= birthday.AddYears(minAge));
        }
    }
}

Attributes

[Authorize]
public class HomeController : Controller
{
    [ClassPrincipalPermission(SecurityAction.Demand, Resource = "Home", Operation = "Index")]
    public ActionResutl Index()
    {
        return View();
    }

    public void Logout()
    {
        Uri signoutUrl = new Uri(FederatedAuthentication.WSFederationAuthenticationModule.Issuer);
        Uri replyUrl = new Uri(Url.Action("Index", "Home", null, Request.Url.Scheme)); // redirect to home after logout 
        WSFederationAuthenticationModule.FederatedSignOut(signoutUrl, replyUrl);
    }
}

OWIN

Important
  • Ensure cross site forgery security for cookie
  • Provide proper Authentication and Authorization provider implementations
public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions {
            AuthenticationType = CookieAuthenticationDefaults.AuthenticationType, 
            // set provider for custom authentication code 
            Provider = new CookieAuthenticationProvider {
                OnResponseSignIn = context => {
                    var authenticationService = new MyAuthenticationService(); // TODO: dependency inject this 
                    var newIdentity = authenticationService .Authenticate(new ClaimsPrincipal(context.Identity));
                    context.Identity = newIdentity;
                }
            }
        });

        app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions{
            SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType, 
            MetadataAddress = "https://my-sts-server-address.com/core/wsfed/metadata", 
            Wtrealm = "urn:myapprealm"
        });
    }
}
// example code only 
// use thinktecture attributes or other proper implementation
public class MyAuthorizeAttribute : AuthorizeAttribute 
{
    public string Resource { get; set; }
    public string Operation { get; set; }
    
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var service = new AuthorizationService(); // TODO: inject this 
        service.CheckAccess(Resource, Operation);
    }
}
[Authorize]
public class HomeController : Controller
{
    [CustomAuthorize(Resource = "Home", Operation = "Index")]
    public ActionResult Index()
    {
        return View();
    }

    public void Logout()
    {
        Request.GetOwinContext().Authentication.SignOut(WsFederationAuthenticationDefaults.AuthenticationType);
    }
}
Cleanup Cookies
app.Use(async(context, next) => {
    var query = context.Request.Query;
    var wa = query.Get("wa");
    if(wa == "wssignoutcleanup1.0"){
        context.Authentication.SignOut("Cookies");
    }
    await next();
});

JWT Token

Produce
// setting up symmetric encryption
using (var hmac = new HMACSHA256(Convert.FromBase64String("c2hhcmVkIHNlY3JldA==")))
{
    const string signatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256";
    const string digestAlgorithm = "http://www.w3.org/2001/04/xmlenc#sha256";

    var signingCredentials = new SigningCredentials(new InMemorySymmetricSecurityKey(hmac.Key), signatureAlgorithm, digestAlgorithm);

    // define the claims
    var claims = new[]
    {
        new Claim(ClaimTypes.Email, "[email protected]"),
    };

    var token = new JwtSecurityToken(
        "http://authorizationserver.com/",
        "http://resourceserver.com/",
        claims,
        DateTime.UtcNow, // valid from
        DateTime.UtcNow.AddMinutes(15), // valid till
        signingCredentials);

    return new JwtSecurityTokenHandler().WriteToken(token); // serialization as JSON string
}
Verify
// setting up symmetric encryption
using(var hmac = new HMACSHA256(Convert.FromBase64String("c2hhcmVkIHNlY3JldA==")))
{
    const string signatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256";
    const string digestAlgorithm = "http://www.w3.org/2001/04/xmlenc#sha256";

    var signingCredentials = new SigningCredentials(new InMemorySymmetricSecurityKey(hmac.Key), signatureAlgorithm, digestAlgorithm);

    // what to validate
    var validationParams = new TokenValidationParameters
    {
        ValidIssuer = "http://authorizationserver.com/",
        ValidAudience = "http://resourceserver.com/",
        ValidateLifetime = true,
        ValidateAudience = true,
        ValidateIssuer = true,
        RequireExpirationTime = true,
        RequireSignedTokens = true,
        IssuerSigningToken = new BinarySecretSecurityToken(hmac.Key),
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = signingCredentials.SigningKey,
        ValidateActor = false
    };

    SecurityToken validatedToken;
    ClaimsPrincipal principal = new JwtSecurityTokenHandler().ValidateToken(tokenString, validationParams, out validatedToken);

    // ...
}

Internetquellen

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.