Set Xamarin WebView Cookie to seamlessly authenticate user without re-entering credentials - ios

I have a Xamarin forms mobile app where the user authenticates using a post REST API and I am going to save the returned ASP.NET session ID and the authentication cookie to later pass it to my WebView in the main page to load a web page that needs authentication. For this, I created a custom web view renderer and followed some guides that suggested how to pass the cookie in the cookie container to the WebView for each request. But that does not work and I get to the login page of our website. Please advise.
WebView Renderer (IOS):
[assembly: ExportRenderer(typeof(CookieWebView), typeof(CookieWebViewRenderer))]
namespace perfectmobile.iOS
{
public class CookieWebViewRenderer: WebViewRenderer
{
public CookieWebView CookieWebView
{
get { return Element as CookieWebView; }
}
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
Delegate = (UIKit.IUIWebViewDelegate)new WebViewDelegate(CookieWebView);
}
}
}
internal class WebViewDelegate : UIWebViewDelegate
{
private CookieWebView _cookieWebView;
public WebViewDelegate(CookieWebView cookieWebView)
{
_cookieWebView = cookieWebView;
}
public override bool ShouldStartLoad(UIWebView webView, NSUrlRequest request, UIWebViewNavigationType navigationType)
{
// Set cookies here
var cookieJar = NSHttpCookieStorage.SharedStorage;
cookieJar.AcceptPolicy = NSHttpCookieAcceptPolicy.Always;
//clean up old cookies
foreach (var aCookie in cookieJar.Cookies)
{
cookieJar.DeleteCookie(aCookie);
}
//set up the new cookies
var jCookies = _cookieWebView.Cookies.GetCookies(request.Url);
IList<NSHttpCookie> eCookies =
(from object jCookie in jCookies
where jCookie != null
select (Cookie)jCookie
into netCookie
select new NSHttpCookie(netCookie)).ToList();
foreach (var ck in eCookies)
{
cookieJar.SetCookie(ck);
}
return true;
}
public override void LoadFailed(UIWebView webView, NSError error)
{
// TODO: Display Error Here
Debug.WriteLine("ERROR: {0}", error.ToString());
}
public override void LoadingFinished(UIWebView webView)
{
}
}
}
//===================PCL project Cookie webview ========//
public class CookieWebView : WebView
{
public static readonly BindableProperty CookiesProperty = BindableProperty.Create(
propertyName: "Cookies",
returnType: typeof(CookieContainer),
declaringType: typeof(CookieWebView),
defaultValue: default(string));
public CookieContainer Cookies
{
get { return (CookieContainer)GetValue(CookiesProperty); }
set { SetValue(CookiesProperty, value); }
}
public CookieWebView()
{
Cookies = new CookieContainer();
}
}
//========= Login ======//
var handler = new HttpClientHandler();
handler.CookieContainer = UserInfo.CookieContainer;
HttpClient client = new HttpClient(handler);
HttpContent content = new StringContent("");
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
Uri uri = new Uri(LoginUrl);
var response = client.PostAsync(uri,content);
var responseResult = response.Result;
if (responseResult.IsSuccessStatusCode)
{
IEnumerable<Cookie> responseCookies = UserInfo.CookieContainer.GetCookies(uri).Cast<Cookie>();
foreach (Cookie cookie in responseCookies)
{
UserInfo.CookieContainer.Add(uri, cookie);
}
}
//======== User Info =======//
public class UserInfo
{
public static CookieContainer CookieContainer = new CookieContainer();
}
// ======== Main Page Xaml =======//
<local:CookieWebView x:Name="webView" Source="Url of the website page " WidthRequest="1000" HeightRequest="1000" />
//========= Main page.cs ==========//
public partial class MainTabbedPage : ContentPage
{
public MainTabbedPage()
{
InitializeComponent();
webView.Cookies = UserInfo.CookieContainer;
}

You need to create a custom control in your PCL-Project and then add a custom webview for each platform. The platform specific implementation then gets the cookies and you can use it from your pcl-webview.
Android
var cookieHeader = CookieManager.Instance.GetCookie(url);
iOS
NSHttpCookieStorage storage = NSHttpCookieStorage.SharedStorage;
And you can check https://github.com/seansparkman/CookiesWebView for more details .

Related

Getting Error 400: invalid_request while redirecting Authorization page

Following this guide (https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth#web-applications-asp.net-mvc) I made the code work in localhost but it gives an Error 400: invalid_request device_id and device_name are required for private IP: http://xx.xx.xx.xx:xxxxx/AuthCallback/IndexAsync while redirecting to Authorization page. We added subdomain in dns for our windows server ip address and registered the same subdomain in google api console. Why google gets ip address of the server instead of subdomain? Is the problem related to dns?
These are the working codes on local machine:
HomeController.cs
public class HomeController : Controller
{
public async Task<ActionResult> Index(CancellationToken cancellationToken)
{
var result = await new AuthorizationCodeMvcApp(this, new AppFlowMetadata()).
AuthorizeAsync(cancellationToken);
if (result.Credential != null)
{
var service = new GmailService(new BaseClientService.Initializer
{
HttpClientInitializer = result.Credential,
ApplicationName = "BPM Mail"
});
var gmailProfile = service.Users.GetProfile("me").Execute();
var userGmailEmail = gmailProfile.EmailAddress;
Utils.userMail = userGmailEmail;
Utils.cred = result.Credential;
// SAMPLE CODE:
//var list = await service.Files.List().ExecuteAsync();
//ViewBag.Message = "FILE COUNT IS: " + list.Items.Count();
return new RedirectResult("~/Apps/Mail/Default.aspx");
}
else
{
return new RedirectResult(result.RedirectUri);
}
}
}
AppFlowMetadata.cs
public class AppFlowMetadata : FlowMetadata
{
private static readonly IAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = "ClientId ",
ClientSecret = "ClientSecret "
},
Scopes = new[] { GmailService.Scope.GmailReadonly, GmailService.Scope.MailGoogleCom, GmailService.Scope.GmailModify },
DataStore = new FileDataStore("D:/bpm_mail/mytokens/token.json", true)
});
public override string GetUserId(Controller controller)
{
// In this sample we use the session to store the user identifiers.
// That's not the best practice, because you should have a logic to identify
// a user. You might want to use "OpenID Connect".
// You can read more about the protocol in the following link:
// https://developers.google.com/accounts/docs/OAuth2Login.
var user = controller.Session["user"];
//Utils.userId = user.ToString();
if (user == null)
{
user = Guid.NewGuid();
controller.Session["user"] = user;
}
return user.ToString();
}
public override IAuthorizationCodeFlow Flow
{
get { return flow; }
}
//public override string AuthCallback
//{
// get { return #"/AuthCallback/IndexAsync"; }
//}
}
AuthCallbackController.cs
public class AuthCallbackController : Google.Apis.Auth.OAuth2.Mvc.Controllers.AuthCallbackController
{
protected override Google.Apis.Auth.OAuth2.Mvc.FlowMetadata FlowData
{
get { return new AppFlowMetadata(); }
}
}
Issue solved by changing private ip to public one and redirect it to domain.

Asp.net SignalR not working while deployed in Azure

I am using Asp.Net signal for sending user specific notification. Everything working fine in debug mode using visual studio but the same breaks while deployed to Azure.
I am using redis cache.
Startup.cs
using Microsoft.AspNet.SignalR;
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(NotifSystem.Web.Startup))]
namespace NotifSystem.Web
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
GlobalHost.DependencyResolver.UseStackExchangeRedis(new RedisScaleoutConfiguration("mySrver:6380,password=password,ssl=True", "YourServer"));
app.MapSignalR();
}
}
}
My Hub Class:
using Microsoft.AspNet.SignalR;
using NotificationHub.Models.Hubs;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace NotificationHub.Hubs
{
public class NotificationHub : Hub
{
private static readonly ConcurrentDictionary<string, UserHubModels> Users =
new ConcurrentDictionary<string, UserHubModels>(StringComparer.InvariantCultureIgnoreCase);
//private NotifEntities context = new NotifEntities();
//Logged Use Call
public void GetNotification()
{
try
{
string loggedUser = Context.User.Identity.Name;
//Get TotalNotification
//string totalNotif = LoadNotifData(loggedUser);
//Send To
UserHubModels receiver;
if (Users.TryGetValue(loggedUser, out receiver))
{
var cid = receiver.ConnectionIds.FirstOrDefault();
var context = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
context.Clients.Client(cid).broadcaastNotif();
}
}
catch (Exception ex)
{
ex.ToString();
}
}
//Specific User Call
public void SendNotification(string SentTo,string Notification)
{
try
{
//Get TotalNotification
//string totalNotif = LoadNotifData(SentTo);
//Send To
UserHubModels receiver;
if (Users.TryGetValue(SentTo, out receiver))
{
var cid = receiver.ConnectionIds.FirstOrDefault();
var context = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
context.Clients.Client(cid).broadcaastNotif(Notification);
}
}
catch (Exception ex)
{
ex.ToString();
}
}
private string LoadNotifData(string userId)
{
return userId;
int total = 0;
//var query = (from t in context.Notifications
// where t.SentTo == userId
// select t)
// .ToList();
total = 6;
return total.ToString();
}
public override Task OnConnected()
{
string userName = Context.User.Identity.Name;
string connectionId = Context.ConnectionId;
var user = Users.GetOrAdd(userName, _ => new UserHubModels
{
UserName = userName,
ConnectionIds = new HashSet<string>()
});
lock (user.ConnectionIds)
{
user.ConnectionIds.Add(connectionId);
if (user.ConnectionIds.Count == 1)
{
Clients.Others.userConnected(userName);
}
}
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
string userName = Context.User.Identity.Name;
string connectionId = Context.ConnectionId;
UserHubModels user;
Users.TryGetValue(userName, out user);
if (user != null)
{
lock (user.ConnectionIds)
{
user.ConnectionIds.RemoveWhere(cid => cid.Equals(connectionId));
if (!user.ConnectionIds.Any())
{
UserHubModels removedUser;
Users.TryRemove(userName, out removedUser);
Clients.Others.userDisconnected(userName);
}
}
}
return base.OnDisconnected(stopCalled);
}
}
}
Javascript Code:
var hub = $.connection.notificationHub;
hub.client.broadcaastNotif = function (notification) {
setTotalNotification(notification)
};
$.connection.hub.start()
.done(function () {
console.log("Connected!");
hub.server.getNotification();
})
.fail(function () {
console.log("Could not Connect!");
});
});
function setTotalNotification(notification) {
if (notification) {
GetUnreadNotificationCount();
$('#m_topbar_notification_icon .m-nav__link-icon').addClass('m-animate-shake');
$('#m_topbar_notification_icon .m-nav__link-badge').addClass('m-animate-blink');
}
else {
$('#m_topbar_notification_icon .m-nav__link-icon').removeClass('m-animate-shake');
$('#m_topbar_notification_icon .m-nav__link-badge').removeClass('m-animate-blink');
}
}
I have enabled Websocket for that particular App Service.
Cross user notification sending is not successful it only works if the logged in user sends notification to himself only.
Update:
I checked that while a logged in user is doing an activity so that the notification goes to that particular user then it works. Like if a user user1 sends a notification to user1 then there is no issue.
We had same problem with our Azure SignalR redis BackPlane POC.
But We tried redis with No SSL port then the Azure SignalR redis BackPlane started working fine. Please check the screenshot Below. Now since the enviorment is self contained we do not need it even HTTPS. We are managing it by Resource Groups and Port Whitelisting.

POST-Request in Xamarin WebView?

I've a simple Xamarin.Forms page with a WebView in it, working well.
Now I want to call POST-Requests (sending form-data) for an URL.
Do I have to create 3 different views for Android, iOS and UWP to achieve that - or is there a way to implement the C# post-request code only once in the shared coded of my Xamarin-Forms project?
As #hvaughan3 says you can use HttpClient, like so (from the shared code of your Xamarin Forms project):
private static HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(30) };
HttpContent content = new StringContent(JsonConvert.SerializeObject(objectToPost), Encoding.UTF8, "application/x-www-form-urlencoded");
var response = await client.PostAsync(new Uri("http://your.url"), content);
if (response.IsSuccessStatusCode) {
var responseFromServer = await response.Content.ReadAsStringAsync();
}
else {
// handle errors
}
Use HTTPcLient for form-URLencoded post request and then create a Custom Webview to handle cookies. Use the CookieWebView Nuget Package created by seansparkman.
Please check https://www.nuget.org/packages/CookieWebView/
POST Request Over Webview
For WkWebview
[assembly: ExportRenderer(typeof(PaymentWebview), typeof(PaymentWebViewRenderer))]
namespace MMFInvestorApp.iOS.Utils
{
public class PaymentWebViewRenderer : WkWebViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (NativeView != null)
{
var request = new NSMutableUrlRequest(new NSUrl(new NSString(paymentwebview.url))); //Your Url
request.HttpMethod = "POST";
request.Body = NSData.FromString(paymentwebview.data); //Data for POST
request["Content-Length"] = req.Body.Length.ToString();
request["Content-Type"] = "application/x-www-form-urlencoded charset=utf-8";
LoadRequest(request);
}
}
}
}
For UIWebview (Deprecated from April 2020
[assembly: ExportRenderer(typeof(PaymentWebview), typeof(PaymentWebViewRenderer))]
namespace MMFInvestorApp.iOS.Utils
{
public class PaymentWebViewRenderer : WebViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (NativeView != null)
{
var paymentwebview = Element as PaymentWebview;
var request = new NSMutableUrlRequest(new NSUrl(new NSString(paymentwebview.url)));//Your Url
request.Body = paymentwebview.data; //Data for POST
request.HttpMethod = "POST";
LoadRequest(request);
}
}
}
}

Confusion on getting access token from google api with mvc

I've been trying to follow a number of tutorials I can find to have an mvc application allow a user to authenticate the app and get the access and refresh tokens back. Unfortunately I can't find any that are clear enough to where I can follow what's going on. I started with google's sample code and then found some others like this one and this one.
When I run my app I'm trying to go to http://localhost:61581/Integration/Google/IndexAsync it hits that method which eventually hits the AppFlowMetadata.GetUserId method and then hits my custom TenixDataStore class' GetAsync method.
The things that are confusing are
First off, am I going to the right url/method? I think I am based on google's code example but not sure.
I thought that the key I would get would be the email address but instead is a GUID. Is that how google identifies a user?
If I'm going to the right url, why does the page just hang and never return. I expected it to open a google authorization page which didn't happen.
Here's my code.
AppFlowMetadata class
using System.Web.Mvc;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Auth.OAuth2.Flows;
using Google.Apis.Auth.OAuth2.Mvc;
using Google.Apis.Gmail.v1;
using Tenix.Domain.Constants;
namespace MyApp.Areas.Integration.Controllers
{
public class AppFlowMetadata : FlowMetadata
{
private static readonly IAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = APIConstants.GMailApiKey,
ClientSecret = APIConstants.GmailApiSecret
},
Scopes = new[] {GmailService.Scope.GmailReadonly},
DataStore = new TenixDataStore()
});
public override IAuthorizationCodeFlow Flow
{
get { return flow; }
}
public override string GetUserId(Controller controller)
{
// In this sample we use the session to store the user identifiers.
// That's not the best practice, because you should have a logic to identify
// a user. You might want to use "OpenID Connect".
// You can read more about the protocol in the following link:
// https://developers.google.com/accounts/docs/OAuth2Login.
var user = controller.Session["UserID"];
if (user == null) return null;
return user.ToString();
}
}
}
GoogleController
using System.Threading;
using System.Threading.Tasks;
using System.Web.Mvc;
using Google.Apis.Auth.OAuth2.Mvc;
using Google.Apis.Gmail.v1;
using Google.Apis.Services;
namespace MyApp.Areas.Integration.Controllers
{
public class GoogleController : Controller
{
public async Task IndexAsync(CancellationToken cancellationToken)
{
if (Session["UserID"] == null)
{
Response.Redirect("~/Login.aspx", true);
}
var result = await new AuthorizationCodeMvcApp(this, new AppFlowMetadata()).AuthorizeAsync(cancellationToken);
if (result.Credential != null)
{
var service = new GmailService(new BaseClientService.Initializer
{
HttpClientInitializer = result.Credential,
ApplicationName = "Tenix Gmail Integration"
});
}
}
}
}
TenixDataStore class
using System;
using System.Threading.Tasks;
using DataBaseUtilitiesTEN;
using Google.Apis.Json;
using Google.Apis.Util.Store;
using Newtonsoft.Json.Linq;
using Synergy.Extensions;
using Tenix.Domain.Data.Respositories;
using Tenix.Domain.Model.Integration;
using Tenix.Domain.Services;
namespace MyApp.Areas.Integration.Controllers
{
public class TenixDataStore : IDataStore
{
private readonly string conStr = ConnectionStrings.GeneralInfo;
private CredentialService _service;
public TenixDataStore()
{
_service = new CredentialService(new CredentialRepository(conStr));
}
public Task StoreAsync<T>(string key, T value)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentException("Key MUST have a value");
var serialized = NewtonsoftJsonSerializer.Instance.Serialize(value);
var jObject = JObject.Parse(serialized);
var access_token = jObject.SelectToken("access_token");
var refresh_token = jObject.SelectToken("refresh_token");
if (access_token == null)
throw new ArgumentException("Missing access token");
if (refresh_token == null)
throw new ArgumentException("Missing refresh token");
_service.SaveUserCredentials(new UserCredential
{
EmailAddress = key,
AccessToken = (string)access_token,
RefreshToken = (string)refresh_token
});
return Task.Delay(0);
}
public Task DeleteAsync<T>(string key)
{
_service.DeleteCredentials(key);
return Task.Delay(0);
}
public Task<T> GetAsync<T>(string userId)
{
var credentials = _service.GetUserCredentials(userId.To<int>());
var completionSource = new TaskCompletionSource<T>();
if (!string.IsNullOrEmpty(credentials.AccessToken))
completionSource.SetResult(NewtonsoftJsonSerializer.Instance.Deserialize<T>(credentials.AccessToken));
return completionSource.Task;
}
public Task ClearAsync()
{
return Task.Delay(0);
}
}
}
AuthCallbackController
using Google.Apis.Auth.OAuth2.Mvc;
namespace MyApp.Areas.Integration.Controllers
{
public class AuthCallbackController : Google.Apis.Auth.OAuth2.Mvc.Controllers.AuthCallbackController
{
protected override FlowMetadata FlowData
{
get { return new AppFlowMetadata(); }
}
}
}
After spending days trying to figure this out and not making any headway with the google api .net libraries I ended up just going with my own implementation which after reading their documentation was at least something I could fully understand. In case anyone could use the code, here's what I ended up with. Still need to do some refactoring, but at this point it's working.
Just need to make sure the AuthorizeResponse and Authorize routes are registered as authorized redirect uris.
public class GoogleController : Controller
{
private readonly CredentialService _credentialService;
private readonly GoogleEndpoints _endpoints;
public GoogleController()
{
_endpoints = new GoogleEndpoints();
_credentialService = new CredentialService(new CredentialRepository(ConnectionStrings.GeneralInfo));
}
private string AuthorizeUrl
{
get
{
return "/Integration/Google/Authorize";
}
}
private string AuthorizeResponseUrl
{
get
{
return "/Integration/Google/AuthorizeResponse";
}
}
private string SaveResponseUrl
{
get
{
return "/Integration/Google/SaveResponse";
}
}
public void Authorize()
{
if (Session["UserID"] == null || Session["Email"] == null)
{
Response.Redirect("~/Login.aspx", true);
Session["LoginSource"] = AuthorizeUrl;
Response.End();
}
else
{
if (Session["SessionId"] == null || Session["SessionId"].ToString().Trim().Length == 0)
Session["SessionId"] = _credentialService.CreateSessionId(Session["UserID"].To<int>());
var url = _endpoints.AuthorizationEndpoint + "?" +
"client_id=" + APIConstants.GMailApiKey + "&" +
"response_type=code&" +
"scope=openid%20email&" +
"redirect_uri=" + AuthorizeResponseUrl + "&" +
"state=" + Session["SessionId"] + "&" +
"login_hint=" + Session["Email"] + "&" +
"access_type=offline";
Response.Redirect(url);
}
}
public ActionResult AuthorizeResponse()
{
var state = Request.QueryString["state"];
if (state == Session["SessionId"].ToString())
{
var code = Request.QueryString["code"];
var values = new Dictionary<string, object>
{
{"code", code},
{"redirect_uri", AuthorizeResponseUrl},
{"client_id", APIConstants.GMailApiKey},
{"client_secret", APIConstants.GmailApiSecret},
{"grant_type", "authorization_code"},
{"scope", ""}
};
var webmethods = new WebMethods();
var tokenResponse = webmethods.Post(_endpoints.TokenEndpoint, values);
var jobject = JObject.Parse(tokenResponse);
var access_token = jobject.SelectToken("access_token");
var refresh_token = jobject.SelectToken("refresh_token");
if (access_token == null || access_token.ToString().Trim().Length == 0)
{
//notify devs something went wrong
return View(new GoogleAuthResponse(tokenResponse, false));
}
var credentials = _credentialService.GetUserCredentials(Session["SessionId"].ToString());
credentials.AccessToken = access_token.ToString();
credentials.RefreshToken = refresh_token.ToString();
credentials.EmployeeId = Session["UserId"].To<int>();
_credentialService.SaveUserCredentials(credentials);
return View(new GoogleAuthResponse("Integration successful!", true));
}
return View(new GoogleAuthResponse("Missing state information.", false));
}
}
And the helper class to get the google endpoints.
public class GoogleEndpoints
{
public GoogleEndpoints()
{
using (var client = new WebClient())
{
var response = client.DownloadString("https://accounts.google.com/.well-known/openid-configuration");
var jobject = JObject.Parse(response);
AuthorizationEndpoint = jobject.SelectToken("authorization_endpoint").ToString();
TokenEndpoint = jobject.SelectToken("token_endpoint").ToString();
}
}
public string AuthorizationEndpoint { get; private set; }
public string TokenEndpoint { get; private set; }
}
The controller uses another couple of helper classes for parsing the json and posting the form data, but that should be pretty straightforward.

Resource Authorization in ASP.net WEP API using Identity Server

I have a ASP.net MVC5 client (WEBAPP) which is authenticated using identity
server . And I'm using the below code to access the web api.
1.Get access token from Identity Server
private async Task<TokenResponse> GetTokenAsync()
{
var client = new TokenClient(
"https://localhost:44301/identity/connect/token",
"mvc_service",
"secret");
return await client.RequestClientCredentialsAsync("sampleApi");
}
And using the access token, I'm calling the WEBAPI
var client = new HttpClient();
client.SetBearerToken(token);
var gg = this.HttpContext;
var json = await client.GetStringAsync("http://localhost:50990/jarvis");
var jsonStr = JArray.Parse(json).ToString();
var model = JsonConvert.DeserializeObject<List<User>>(jsonStr);
The web api is secured by identity server and Resource Authotization provided by the IdentityServer (Thinktecture.IdentityModel.Owin.ResourceAuthorization.WebApi)
The APIController is as below
[Authorize]
public class AuthorizationController : ApiController
{
[ResourceAuthorize(AuthorizationResources.AdminActions.Create, AuthorizationResources.Admin)]
public async Task<IHttpActionResult> Get()
{
var user = User as ClaimsPrincipal;
List<User> usersList = await GetUsers();
return Json(usersList);
}
}
And my ResourceAuthorize is as below
ResourceAuthorize
public class APIAuthorization: ResourceAuthorizationManager
{
public override Task<bool> CheckAccessAsync(ResourceAuthorizationContext context)
{
var resource = context.Resource.First().Value;
if (resource == AuthorizationResources.Admin)
{
return CheckAdminAccessAsync(context);
}
if (resource == AuthorizationResources.Editor)
{
return CheckEditorAccessAsync(context);
}
if (resource == AuthorizationResources.Reader)
{
return CheckReaderAccessAsync(context);
}
return Nok();
}
private Task<bool> CheckReaderAccessAsync(ResourceAuthorizationContext context)
{
return Eval(context.Principal.IsInRole("Admin"));
}
private Task<bool> CheckEditorAccessAsync(ResourceAuthorizationContext context)
{
return Eval(context.Principal.IsInRole("Admin"));
}
private Task<bool> CheckAdminAccessAsync(ResourceAuthorizationContext context)
{
return Eval(context.Principal.IsInRole("Admin"));
}
}
My Question are
How do i pass the claims to the WEBAPI so i can do a check in the APIAuthorization:
Eval(context.Principal.IsInRole("Admin"))
Is this the right way to do Resource Authorization?
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "https://localhost:44333/core",
RequiredScopes = new[] { "profile", "openid" },
});**This is what i was looking for , This solved my problem**

Resources