c# - Custom Authorize Attribute on asp.net mvc -
i have asp.net mvc app authorizes azure aad. app based on github example:
https://github.com/dushyantgill/vipswapper/tree/master/trainingpoint
this app has custom authorize attribute
public class authorizeuserattribute : authorizeattribute { protected override void handleunauthorizedrequest(authorizationcontext ctx) { if (!ctx.httpcontext.user.identity.isauthenticated) base.handleunauthorizedrequest(ctx); else { ctx.result = new viewresult { viewname = "error", viewbag = { message = "unauthorized." } }; ctx.httpcontext.response.statuscode = 403; } } }
however seems odd me.
i have on controller this:
public class globaladmincontroller : controller { // get: globaladmin [authorizeuser(roles = "admin")] public actionresult index() { return view(); } }
as can see custom attribute used there, take deeper @ code of custom attribute. apparently on both if , else request not authenticated.
now take @ screenshot.
makes no sense right? http://screencast.com/t/obqxhzjj0ing
the question, should allow user execute controller?
update 1: on auth flow have following
public void configureauth(iappbuilder app) { // configure authentication type & settings app.setdefaultsigninasauthenticationtype(cookieauthenticationdefaults.authenticationtype); app.usecookieauthentication(new cookieauthenticationoptions()); // configure owin openid connect options app.useopenidconnectauthentication(new openidconnectauthenticationoptions { clientid = settingshelper.clientid, authority = settingshelper.azureadauthority, notifications = new openidconnectauthenticationnotifications() { // when auth code received... authorizationcodereceived = (context) => { // openid connect code passed azure ad on successful auth string code = context.code; // create app credentials & reference user clientcredential creds = new clientcredential(settingshelper.clientid, settingshelper.clientsecret); string userobjectid = context.authenticationticket.identity.findfirst(system.identitymodel.claims.claimtypes.nameidentifier).value; // use adal obtain access token & refresh token... // save in persistent store... efadaltokencache samplecache = new efadaltokencache(userobjectid); authenticationcontext authcontext = new authenticationcontext(settingshelper.azureadauthority, samplecache); // obtain access token azuread graph uri redirecturi = new uri(httpcontext.current.request.url.getleftpart(uripartial.path)); authenticationresult authresult = authcontext.acquiretokenbyauthorizationcode(code, redirecturi, creds, settingshelper.azureadgraphresourceid); if (graphutil.isuseraadadmin(context.authenticationticket.identity)) context.authenticationticket.identity.addclaim(new claim("roles", "admin")); // successful auth return task.fromresult(0); }, authenticationfailed = (context) => { context.handleresponse(); return task.fromresult(0); } }, tokenvalidationparameters = new system.identitymodel.tokens.tokenvalidationparameters { validateissuer = false } }); }
check specially isaadadmin method call
/// <summary> /// global administrators , user account administrators of directory automatically assgined admin role in application. /// method determines whether user member of global administrator or user account administrator directory role. /// roletemplateid of global administrator role = 62e90394-69f5-4237-9190-012177145e10 /// roletemplateid of user account administrator role = fe930be7-5e62-47db-91af-98c3a49a38b1 /// </summary> /// <param name="objectid">the objectid of user or group has access.</param> /// <returns>string containing display string user or group.</returns> public static bool isuseraadadmin(claimsidentity identity) { string tenantid = identity.findfirst("http://schemas.microsoft.com/identity/claims/tenantid").value; string signedinuserid = identity.findfirst(system.identitymodel.claims.claimtypes.nameidentifier).value; string userobjectid = identity.findfirst("http://schemas.microsoft.com/identity/claims/objectidentifier").value; clientcredential credential = new clientcredential(settingshelper.clientid, settingshelper.clientsecret); // initialize authenticationcontext token cache of signed in user, kept in app's ef db authenticationcontext authcontext = new authenticationcontext(settingshelper.azureadauthority, new efadaltokencache(signedinuserid)); authenticationresult result = authcontext.acquiretokensilent( settingshelper.azureadgraphresourceid, credential, new useridentifier(userobjectid, useridentifiertype.uniqueid)); httpclient client = new httpclient(); string doqueryurl = string.format("{0}/{1}/users/{2}/memberof?api-version={3}", settingshelper.azureadgraphresourceid, tenantid, userobjectid, settingshelper.graphapiversion); httprequestmessage request = new httprequestmessage(httpmethod.get, doqueryurl); request.headers.authorization = new authenticationheadervalue("bearer", result.accesstoken); httpresponsemessage response = client.sendasync(request).result; if (response.issuccessstatuscode) { var responsecontent = response.content; string responsestring = responsecontent.readasstringasync().result; var memberofobjects = (system.web.helpers.json.decode(responsestring)).value; if (memberofobjects != null) foreach (var memberofobject in memberofobjects) if (memberofobject.objecttype == "role" && ( memberofobject.roletemplateid.equals("62e90394-69f5-4237-9190-012177145e10", stringcomparison.invariantcultureignorecase) || memberofobject.roletemplateid.equals("fe930be7-5e62-47db-91af-98c3a49a38b1", stringcomparison.invariantcultureignorecase))) return true; } return false; }
i 100% sure user in admin role, because when debug returns true , claim created
update 2: @ debugging time checked user.claims , role admin in there. not sure how authorization per role works user.isinrole
esteban, seem have missed setting role claim type in configureauth implementation. please see line 55 of sample: https://github.com/dushyantgill/vipswapper/blob/master/trainingpoint/app_start/startup.auth.cs#l55. once user.isinrole() , authorize attribute work properly.
regd implementation of custom authorize attribute - asp.net has bug returns 401 error (instead of 403) authorization failed (that puts authenticated user in endless auth loop idp). custom authorize attribute fixes issue.
hope helps.
see you.
Casino Games Near Me - MapYRO
ReplyDeleteFind all the Casinos 정읍 출장마사지 Near Me 강릉 출장샵 in 당진 출장샵 2021 - Use our list to find the BEST & NEW CASINOS in 포천 출장샵 LOUISIANA. Find 아산 출장샵 your Casino Hotel near you in LOUISIANA!