https://msdn.microsoft.com/en-us/magazine/dn781361.aspx
使用开放令牌;
使用 PF.SAML.Result;
使用系统;
使用 System.Collections.Generic;
使用 System.Configuration;
使用 System.Linq;
使用 System.Net.Http;
使用 System.Net.Http.Headers;
使用 System.Security.Claims;
使用 System.Text;
使用 System.Threading;
使用 System.Threading.Tasks;
使用 System.Web.Http.Filters;
命名空间 PF.SAML.Filters
{
公共类 PingAuthenticationAttribute : IAuthenticationFilter
{
公共布尔 AllowMultiple { 获取 { 返回 false; } }
// http://www.asp.net/web-api/overview/security/authentication-filters
// https://msdn.microsoft.com/en-us/magazine/dn781361.aspx
public async Task AuthenticateAsync( HttpAuthenticationContext context, CancellationToken cancellationToken )
{
await Task.Run( () => {
/*
* Look for credentials in the request.
* If there are no credentials, do nothing and return (no-op).
* If there are credentials but the filter does not recognize the authentication scheme, do nothing and return (no-op). Another filter in the pipeline might understand the scheme.
* If there are credentials that the filter understands, try to authenticate them.
* If the credentials are bad, return 401 by setting context.ErrorResult.
* If the credentials are valid, create an IPrincipal and set context.Principal.
*/
var opentoken = context.Request.Headers.GetCookies()
.SelectMany( c => c.Cookies )
.Where( c => c.Name == "opentoken" )
.FirstOrDefault();
if( opentoken == null ) return;
var userInfo = getOpenToken( opentoken.Value );
if( userInfo == null ) {
context.ErrorResult = new AuthenticationFailureResult( "Invalid Token", context.Request );
return;
}
var claims = new List<Claim>();
foreach( var item in userInfo ) {
foreach( var value in userInfo[item.Key] ) {
claims.Add( new Claim( item.Key, value ) );
}
}
var id = new ClaimsIdentity( claims, "opentoken" );
var principle = new ClaimsPrincipal( new[] { id } );
context.Principal = principle;
} );
}
public async Task ChallengeAsync( HttpAuthenticationChallengeContext context, CancellationToken cancellationToken )
{
await Task.Run( () => {
var challenge = new AuthenticationHeaderValue( "SAML" );
context.Result = new AddChallengeOnUnauthorizedResult( challenge, context.Result );
} );
}
private MultiStringDictionary getOpenToken( string token )
{
MultiStringDictionary attributes = null;
Configuration.Agent agentConfig = (Configuration.Agent) ConfigurationManager.GetSection( "pfConfigurationGroup/agentConfiguration" );
AgentConfiguration config = new AgentConfiguration
{
CookieDomain = agentConfig.CookieDomain,
CookiePath = agentConfig.CookiePath,
NotBeforeTolerance = agentConfig.NotBeforeTolerance,
ObfuscatePassword = agentConfig.ObfuscatePassword,
RenewUntilLifetime = agentConfig.RenewUntilLifetime,
SecureCookie = agentConfig.SecureCookie,
SessionCookie = agentConfig.SessionCookie,
TokenLifetime = agentConfig.TokenLifetime,
TokenName = agentConfig.TokenName,
UseCookie = agentConfig.UseCookie,
UseSunJCE = agentConfig.UseSunJCE,
UseVerboseErrorMessages = agentConfig.UseVerboseErrorMessages
};
var str = ( config.ObfuscatePassword
? Encoding.UTF8.GetString( Obfuscator.Deobfuscate( agentConfig.Password ) )
: Encoding.ASCII.GetString( Convert.FromBase64String( agentConfig.Password ) ) );
config.SetPassword( str, Token.CipherSuite.AES_128_CBC );
// TODO: Check for token expiration
Agent agent = new Agent( config );
attributes = agent.ReadTokenMultiStringDictionary( token );
return attributes;
}
}
}