驗證(Authentication)和授權(Authorization)(一):


 

采用ASP.NET Web API 提供的IAuthenticationFilter和IAuthorizationFilter接口分別實現驗證和授權。其中用到IIdentity和IPrincipal接口。

IIdentity的具體類型用來標識通過驗證的用戶身份,由用戶憑據(Credential)來創建一個指定名稱的用戶。

接口定義:

    //定義標識對象的基本功能。

    public interface IIdentity

    {

        // 獲取所使用的身份驗證的類型。

        string  AuthenticationType { get; }

        // 獲取一個值,該值指示是否驗證了用戶。

        bool  IsAuthenticated { get; }

        // 獲取當前用戶的名稱

        string  Name { get; }

    }

不同的驗證類型,對IIdentity有不同的實現方式。如:WindowsIdentity(Windows集成)、FormsIdentity(Forms)和GenericIdentity(一般用戶)等。

如果自定義實現驗證方式,可以采用GenericIdentity來標識用戶身份,已通過驗證的用戶是一個指定名稱的GenericIdentity。

GenericIdentity類型定義:

  public class GenericIdentity : ClaimsIdentity

    {

        //     使用指定的 System.Security.Principal.GenericIdentity 對象初始化 System.Security.Principal.GenericIdentity

        //     類的新實例。

        protected GenericIdentity(GenericIdentity identity);

        //     初始化 System.Security.Principal.GenericIdentity 類的新實例,該類表示具有指定名稱的用戶。

        public GenericIdentity(string name);

        //     初始化 System.Security.Principal.GenericIdentity 類的新實例,該類表示具有指定名稱和身份驗證類型的用戶。

        public GenericIdentity(string name, string type);

        //     獲取用於標識用戶的身份驗證的類型。

        public override string AuthenticationType { get; }

        //     為用戶獲取此最常用標識表示的所有聲明。

        public override IEnumerable<Claim> Claims { get; }

        //     獲取一個值,該值指示是否驗證了用戶。

        public override bool IsAuthenticated { get; }

        //     獲取用戶的名稱。

        public override string Name { get; }

        //     創建作為當前實例副本的新對象。

        public override ClaimsIdentity Clone();

    }

IPrincipal的具體類型表示一個已通過驗證並獲得授權的對象。

接口定義:

    public interface IPrincipal

    {

        //     獲取當前用戶的標識。

        IIdentity Identity { get; }

        //     確定當前用戶是否屬於指定的角色。

        bool IsInRole(string role);

    }

GenericPrincipal類型,用用戶標識和角色名稱數組來初始化。

    public class GenericPrincipal : ClaimsPrincipal

    {

        //     從用戶標識和角色名稱數組(標識表示的用戶屬於該數組)初始化 System.Security.Principal.GenericPrincipal

        //     類的新實例。

        public GenericPrincipal(IIdentity identity, string[] roles);

        //     獲取當前 System.Security.Principal.GenericPrincipal 表示的用戶的 System.Security.Principal.GenericIdentity。

        public override IIdentity Identity { get; }

        //     確定當前 System.Security.Principal.GenericPrincipal 是否屬於指定的角色。

        public override bool IsInRole(string role);

    }

IAuthenticationFilter接口定義:

public interface IAuthenticationFilter : IFilter
{
Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken);
Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken);
}

其中AuthenticateAsync方法用於實現用戶認證,而ChallengeAsync方法在認證失敗的情況下,生成“質詢(Challenge)”結果。

用自定義AuthenticateAttribute類型實現Basic認證:

[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method)]
public class AuthenticateAttribute : FilterAttribute, IAuthenticationFilter
{
private static readonly Dictionary<string, string> UserAccount;
static AuthenticateAttribute()
{
UserAccount = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{"CHN", "china"}
};
}

public Task AuthenticateAsync(HttpAuthenticationContext context,
System.Threading.CancellationToken cancellationToken)
{
var headerValue = context.Request.Headers.Authorization;

if (null == headerValue || headerValue.Scheme != "Basic")
return Task.Factory.StartNew(() => { }, cancellationToken);

var byteArray = Convert.FromBase64String(headerValue.Parameter);
var credential = Encoding.UTF8.GetString(byteArray);
var split = credential.Split(':');

if (split.Length != 2) return Task.Factory.StartNew(() => { }, cancellationToken);

var userName = split[0];
string password;

if (!UserAccount.TryGetValue(userName, out password))
return Task.Factory.StartNew(() => { }, cancellationToken);

if (password != split[1]) return Task.Factory.StartNew(() => { }, cancellationToken);

var identity=new GenericIdentity(userName);
IPrincipal user = new GenericPrincipal(identity,new string[0]);
context.Principal = user;

return Task.FromResult<object>(null);
}

public Task ChallengeAsync(HttpAuthenticationChallengeContext context,
System.Threading.CancellationToken cancellationToken)
{
var user = context.ActionContext.ControllerContext.RequestContext.Principal;

if (null != user && user.Identity.IsAuthenticated)
return Task.Factory.StartNew(() => { }, cancellationToken);

var parameter = string.Format("realm=\"{0}\"", context.Request.RequestUri.DnsSafeHost);
var challenge=new AuthenticationHeaderValue(
"Basic",parameter);
context.Result=new UnauthorizedResult(new[]{challenge},
context.Request);

return Task.FromResult<object>(null);
}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM