2

私はMVCプロジェクトに取り組んでいます。カスタム認証属性を使用したいと思います。まず、this blog postの例を使用しました。Asp.Net MVCカスタム認証が機能しない

public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 
    public string RolesConfigKey { get; set; } 

    protected virtual CustomPrincipal CurrentUser => HttpContext.Current.User as CustomPrincipal; 

    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if (!filterContext.HttpContext.Request.IsAuthenticated) return; 
     var authorizedRoles = ConfigurationManager.AppSettings["RolesConfigKey"]; 

     Roles = string.IsNullOrEmpty(Roles) ? authorizedRoles : Roles; 

     if (string.IsNullOrEmpty(Roles)) return; 
     if (CurrentUser == null) return; 
     if (!CurrentUser.IsInRole(Roles)) base.OnAuthorization(filterContext); 
    } 

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     if (!filterContext.HttpContext.Request.IsAuthenticated) return; 
    } 
} 

私はベースコントローラでこのカスタムプリンシパルを使用します。私は私のデフォルトルートをrouteconfigで

public class CustomPrincipal : IPrincipal 
{ 
    public CustomPrincipal(string userName) { this.Identity = new GenericIdentity(userName); } 

    public bool IsInRole(string userRoles) 
    { 
     var result = true; 
     var userRolesArr = userRoles.Split(','); 
     foreach (var r in Roles) 
     { 
      if (userRolesArr.Contains(r)) continue; 
      result = false; 
      break; 
     } 
     return result; 
    } 

    public IIdentity Identity { get; } 
    public string UserId { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string[] Roles { get; set; } 
} 

ユーザーが操作でログイン/Account/Indexである。そしてこれは、アカウント・コントローラのindexアクションです。ユーザーが管理者の役割であるときにあなたが見ることができるように

[HttpPost, ValidateAntiForgeryToken] 
    public ActionResult Index(AccountViewModel accountModel) 
    { 
     var returnUrl = string.Empty; 

     if (!ModelState.IsValid) { return UnsuccessfulLoginResult(accountModel.UserName, ErrorMessages.WrongAccountInfo); } 

     var account = _accountService.CheckUser(accountModel.UserName, accountModel.Password); 
     if (account == null) return UnsuccessfulLoginResult(accountModel.UserName, ErrorMessages.WrongAccountInfo); 

     var roles = account.Roles.Select(r => r.RoleName).ToArray(); 
     var principalModel = new CustomPrincipalModel 
     { 
      UserId = account.UserId, 
      FirstName = "FirstName", 
      LastName = "LastName", 
      Roles = roles 
     }; 

     var userData = JsonConvert.SerializeObject(principalModel); 
     var ticket = new FormsAuthenticationTicket(1, account.UserId, DateTime.Now, DateTime.Now.AddMinutes(30), false, userData); 
     var encryptedTicket = FormsAuthentication.Encrypt(ticket); 
     var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); 
     Response.Cookies.Add(cookie); 

     SetCulture(account.DefaultCulture); 

     if (!Array.Exists(roles, role => role == "admin" || role == "user")) return UnsuccessfulLoginResult(accountModel.UserName, ErrorMessages.WrongAccountInfo); 

     if (roles.Contains("admin")) { returnUrl = Url.Action("Index", "Admin"); } 
     if (roles.Contains("user")) { returnUrl = Url.Action("Index", "Upload"); } 

     return SuccessfulLoginResult(accountModel.UserName, returnUrl); 
    } 

このアクションは、ユーザー/Admin/Indexそう/Upload/Indexリダイレクトします。しかし、ユーザーがログインした後にユーザーの役割があり、/Admin/Indexと入力すると、承認フィルターが機能せず、ユーザーは管理ページにアクセスできます。

UploadControllerとAdminControllerにこの属性を追加しましたが、このエラーが発生しています。これをどうすれば解決できますか?

[CustomAuthorize(Roles = "user")] 
public class UploadController : BaseController 

[CustomAuthorize(Roles = "admin")] 
public class AdminController : BaseController 
+0

ユーザークレームを追加する場所はどこですか? – SeM

答えて

0

問題。私CustomAuthorizeAttributeで

if (!filterContext.HttpContext.Request.IsAuthenticated) base.OnAuthorization(filterContext); 

にこのライン

if (!filterContext.HttpContext.Request.IsAuthenticated) return; 

を変更し、私は、Web設定から許可されたロールを読んで行を削除しました。だから、

public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected virtual CustomPrincipal CurrentUser => HttpContext.Current.User as CustomPrincipal; 

    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if (!filterContext.HttpContext.Request.IsAuthenticated) base.OnAuthorization(filterContext); 

     if (string.IsNullOrEmpty(Roles)) return; 
     if (CurrentUser == null) return; 
     if (!CurrentUser.IsInRole(Roles)) filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Error", action = "AccessDenied" })); 
    } 
} 

以下のように私の属性の最終バージョンはその後、私はのErrorControllerという名前のコントローラを追加していない役割でたときに、ユーザー、このページにリダイレクト。

これらの変更により、/Account/Indexにアクセスできず、以下の操作に[AllowAnonymous]属性が追加されたことがわかりました。

[AllowAnonymous] 
    public ActionResult Index() { return View(); } 

    [HttpPost, ValidateAntiForgeryToken, AllowAnonymous] 
    public ActionResult Index(AccountViewModel accountModel) 
0

あなたは、あなたのユーザーのための請求を追加する方法には、この部分を追加する必要があります。これらの変更で解決

. . .  

var roles = account.Roles.Select(r => r.RoleName).ToArray(); 

ClaimsIdentity identity = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie); 

identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, accountModel.UserName)); 

roles.ToList().ForEach((role) => identity.AddClaim(new Claim(ClaimTypes.Role, role))); 

identity.AddClaim(new Claim(ClaimTypes.Name, userCode.ToString())); 

. . . 
+0

私はクレームの使い方を知らない。私はフォームベースの認証を使用しました。クレームとフォーム認証を一緒に使うことはできますか? –

+0

私はこれを追加しましたが動作しません –

+0

ウェブで ' 'があれば可能です。設定、それをコメントしてください。 – SeM

関連する問題