title: IdentityServer3 Authorize in custom MVC controller in identity server application
body: <p>I have an Identity Server 3 application used for SSO. In the same application in which the IdentityServer is running I have integrated Asp.Net MVC controllers for user registration and so on. However I have some methods which cannot be accessed without a specific role and I want to use the Authorize attribute in order to do the role check.</p>
  
  <p>As per this GitHub thread <a href="https://github.com/IdentityServer/IdentityServer3/issues/1148" rel="nofollow noreferrer">https://github.com/IdentityServer/IdentityServer3/issues/1148</a> I have setup said controller to use the same base route as IdentityServer in order to be in the Owin pipeline.</p>
  
  <p>In the thread there is an attribute snippet which in general does what I want. It authenticates the user and gets some of their claims, but the problem is that many claims are missing- the role claim, for example, which I need for the Authorize attribute to work. I spent many hours trying to see why there are missing claims and really want to avoid querying the database and adding them myself.</p>
  
  <p>In my normal client applications the claims I get in the ClaimsPrincipal are (iss,aud,exp,nbf,nonce,iat,sid,sub,auth_time,idp,preferred_username,email,email_verified,role,website,amr). As you will see apart from sub and amr, the other claims are completely different from what I get in the IdentitySever application with the help of IdentityServerFullLoginAttribute (code below).</p>
  
  <p>The question is is that even possible and why are just these claims retrieved(sub, name, amr, idp, auth_time, security_stamp)?</p>
  
  <p>This is my IdentityServer config:</p>
  
  <pre><code>coreApp.UseIdentityServer(new IdentityServerOptions
              {
                  Factory = factory,
                  SigningCertificate = signingCertificate,
                  SiteName = "Sitename",
                  RequireSsl = true,
                  LoggingOptions = new LoggingOptions
                  {
                      EnableKatanaLogging = true
                  },
                  EventsOptions = new EventsOptions
                  {
                      RaiseFailureEvents = true,
                      RaiseInformationEvents = true,
                      RaiseSuccessEvents = true,
                      RaiseErrorEvents = true
                  },
                  CspOptions = new CspOptions
                  {
                      Enabled = true,
                      ScriptSrc = "'unsafe-eval' 'unsafe-inline'"
                  }
              });
          });
  </code></pre>
  
  <p>And this is the said attribute I am using to allow the user to be authenticated</p>
  
  <pre><code>public abstract class OwinAuthenticationAttribute : FilterAttribute, IAuthenticationFilter
  {
      public string AuthenticationType { get; set; }
  
      protected OwinAuthenticationAttribute(string authenticationType)
      {
          if (String.IsNullOrWhiteSpace(authenticationType)) throw new ArgumentNullException("authenticationType");
  
          AuthenticationType = authenticationType;
      }
  
      public virtual void OnAuthentication(AuthenticationContext filterContext)
      {
          var ctx = filterContext.HttpContext.Request.GetOwinContext();
          var result = AsyncHelper.RunSync(() =&gt; ctx.Authentication.AuthenticateAsync(AuthenticationType));
          if (result != null &amp;&amp;
              result.Identity != null &amp;&amp;
              result.Identity.IsAuthenticated)
          {
              filterContext.Principal = new ClaimsPrincipal(result.Identity);
          }
      }
  
      public abstract void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext);
  }
  
  public class IdentityServerFullLoginAttribute : OwinAuthenticationAttribute
  {
      public IdentityServerFullLoginAttribute()
          : base(Constants.PrimaryAuthenticationType)
      {
          this.Order = 1;
      }
  
      public override void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
      {
          var statusCodeResult = filterContext.Result as HttpStatusCodeResult;
          if (statusCodeResult != null &amp;&amp; statusCodeResult.StatusCode == 401)
          {
              var ctx = filterContext.HttpContext.Request.GetOwinContext();
              var url = ctx.Environment.CreateSignInRequest(new SignInMessage
              {
                  ReturnUrl = filterContext.HttpContext.Request.Url.AbsoluteUri
              });
              filterContext.Result = new RedirectResult(url);
          }
      }
  }
  </code></pre>
  
  <p>And this is the controller action:</p>
  
  <pre><code>    [HttpGet]
      [Route("core/test/test")]
      [IdentityServerFullLogin]
      [Authorize(Roles = "Administrator")]
      public EmptyResult Test(string signin)
      {
          //return Redirect("~/core/" + IdentityServer3.Core.Constants.RoutePaths.Login + "?signin=" + signin);
  
          return new EmptyResult();
      }
  </code></pre>