ASP.NET Core API Facebook registration/login - oauth-2.0

I'm working on ASP.NET Core API and need to add option to register with social service, e.g. Facebook.
Scenario should be e.g. Android App user should click "Sign up with Facebook" at startup, then Facebook app should open then user should click confirm and be registered in app.
Default Asp.net web example shows how to do it with web page on same host as APIs with return Challenge() response that basically returns HTML page as I understood.
What is the correct flow here and is there any existing libraries to do that?
As I understand now flow is something like this:
1. API server has my AppId and AppSecret from Facebook
2. Android app should request "applciation token" from API server
3. Android app should call Facebook with that token and get "user confirmation token"
4. Android app should pass "user confirmation token" to API server
5. API server should call Facebook with "AppId/AppSecret token + user confrimation token" and get details about user and create local user in database.
6. API server should create "API token" for that user
7. Android app should use "API token"
So at least I want to understand what to replace this code from example with:
public IActionResult ExternalLogin(string provider, string returnUrl = null) {
// Request a redirect to the external login provider.
var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl });
var properties = signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return Challenge(properties, provider);

the thing to understand is the default web app template provided in VS 2015 uses ASP.NET Identity with cookie authentication. cookie auth works for web browsers but for an android app to authenticate you would need something to issue jwt tokens in addition to or instead of cookies. There is nothing built in provided by Microsoft for that in asp.net core, the recommendation is to use IdentityServer4

Related

How to log out from application but not from Azure AD?

In my Asp.Net MVC application, I have recently integrated Azure AD authentication. The login is working fine, but I am not able to get the logout right. I would like to log the users out from my application only, and not "single sign out". Everything I have read is about single sign out. Here is what I have tried:
Abandon the session and redirect to login page. An error related to missing claims is thrown on the login page on Html.AntiForgeryToken() statement
Session.Abandon();
return RedirectToAction("Index", "Login");
This has the same error as #1
FederatedAuthentication.SessionAuthenticationModule.SignOut();
FederatedAuthentication.SessionAuthenticationModule.DeleteSessionTokenCookie();
return RedirectToAction("Index", "Login");
This takes user to single sign out
HttpContext.GetOwinContext().Authentication.SignOut(OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType);
Here are a few of workarounds as suggested by #Jan Hajek here
Make sure that Azure AD is listed as a Connected Service in your .NET application.
This will prevent a single logout.
We can create single sign out endpoint in controller as below example
return SignOut(
new AuthenticationProperties
{
RedirectUri = callbackUrl,
},
CookieAuthenticationDefaults.AuthenticationScheme
);
NOTE: - When we hit the logout, it clears the cookies which is correct, because the user session (in case of Razor Pages and MVC) is stored in Cookies .
Also we can set redirect logout url (e.g- "<your-doman>/.auth/logout") to the home page of the application itself where it ask for log in again .
For more information please refer the below links
MS BLOG: Expanding App Service Authentication/Authorization
SO THREAD
MS DOC: Customize sign-in and sign-out in Azure App Service authentication

BOT framework External client authentication

I launch the client web application from the BOT framework to process the thrid party authentication. The client application process the the third party authentication using OAuth and Owin. Is there any way to send the useridentity back to the BOT framework?
and able to get the access token from the client browser. But the same api call is not working from the BOT framework or from other client. (Ex: Httpget (clientappurl/api/GetToken)
Any ideas?
//api/GetToken ---GET
public string GetToken()
{
var identity = new ClaimsIdentity (User.Identity.AuthenticateType)
identity.AddClaim ("sub", User.Identity.GetUserName()))
AuthenticationTicket ticket = new AuthenticationTicket (identity,
AuthenticationProperties());
string token = Startup. OAuthOptions.AccessTokenFormat.Protect(ticket);
return token;
}
I think what you are looking for is called the backchannel. There is an example in this link that may be all you need. There is also another example here https://github.com/Microsoft/BotFramework-WebChat/blob/master/samples/backchannel/index.html. The backchannel will allow you to communicate between the client and the bot.

Asp .Net Identity 2 OAuth via Google+ error in production server

I am getting the problem when I use Asp .Net Identity 2 connect Google+. Currently, my website connect Google+ via OAuth API 2 and use Claim Identity store some information of users. I was setup fine in running localhost with https. But the problem appear when I deploy my website into production server. After use accept to provide permission for my website to get his information, Google+ callback my website with url /signin-google. And after that, ASP .Net MVC automatically redirect to ExternalCallBack action but it is get error ?error=access_denied. I have capture the network and see information below:
In url callback signin-google:
signin-google?state=nNABsQBmwoPILh1mViOUIqzDcxQIS3HVZx2jtrSYCwd-ifMn4bDgBV1H1qdewFZx5Lz1c35ZZEpUem9jDTUrKlzWDuV-MwTQ3Tesx66PEjWdQQHo0QPJHX_bRMHqgN-Ad1whLs4iUyUSCH39oeTvYg3Cx6O0_v7Sc5GaUujHgr6xW1jw8EImhWJgnFGXgkAjD5hOtr7RoYO23xJyw0AIyuWnyx1gInJndWKvL-eqWPD9BtRaNe3nhWF5NGEG_2Ir&code=4/OEwsZCeeDPKrN5Dls3Uu-Q0wacdMqlhdbb8B1P__8X8.MmSgAQ_-cmIRgrKXntQAax20FxCmlQI
Asp.Net.Collrelation.Google nXgdr60bDh6tfivnvc6NA6ubz1K9zwjOqgrBBQgsitE
In URL callback external-login:
external-login-callback?error=access_denied
Hope you help me.
*Edit:
This is my code in Startup.Config.cs
var googleOpt = new GoogleOAuth2AuthenticationOptions()
{
ClientId = "xxxxxxxxpm0il.apps.googleusercontent.com",
ClientSecret = "xxxxxxxx",
Provider = new GoogleOAuth2AuthenticationProvider()
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("GoogleAccessToken", context.AccessToken));
return Task.FromResult(o);
}
}
};
googleOpt.Scope.Add("https://www.googleapis.com/auth/plus.login");
googleOpt.Scope.Add("https://www.googleapis.com/auth/plus.profile.emails.read");
googleOpt.SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie;
app.UseGoogleAuthentication(googleOpt);
And in my account controller I use default code of Asp .Net MVC 5.2
I had the same issue and had to enable the Google+ API in the Google Developer Console.
If this is turned off, it will not work. As soon as I turned it on, everything was fine.

ASPNet Identity Authentication MVC5 Client web site->Auth Server-> Web API server

I'm a newbie for ASPnet identity services and we require a following requirement.
Following is the architecture setup
1. Appserver
Appsever having
a. Entity Framework
b. ASP.Net Web API2 Odata services
c. Authorization server
2. Webserver
ASP.Net MVC 5 application (Client which access the App server)
The flow needs to be
MVC5 Cleint application having a login / Register form
While register / login the information needs to send to the authorization server int he app server, Authorize and creating the claims using Identity Services.
Once the Identity has been created in the Authorization server, the client application should logged in
I'm aware of getting bearer token from authentication server and that will be used as header information to access the API service
All we are lacking is the MVC client application should use the same identity claims that have created in the Authorization server.
Is there any way to access the claims which are created in the auth server.
I have got some samples about how to authenticate in the auth server and receiving token though OWIN and from this token we can access the API securely but I need of the client web application needs to sign in based on the token
I have gone through the following links
http://blogs.msdn.com/b/webdev/archive/2013/09/20/understanding-security-features-in-spa-template.aspx
Also, I require to add claims when ever it requires after login as well
I have resolve this issue as follows, but I'm not sure this is the effective method
Once log-in and retrieve the bearer token (this token should assigned with claims identity already such as username, role .. etc)
In the web api AccountController, need to create a method to retrieve the default claims which requires for client web application. Please check the follows
[Authorize]
[HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
[Route("UserInfo")]
public UserInfoViewModel GetUserInfo()
{
var firstname = ((ClaimsIdentity)User.Identity).Claims.Where(c => c.Type.Equals("FirstName")).SingleOrDefault();
var lastname = ((ClaimsIdentity)User.Identity).Claims.Where(c => c.Type.Equals("LastName")).SingleOrDefault();
var IsApproved = ((ClaimsIdentity)User.Identity).Claims.Where(c => c.Type.Equals("IsApproved")).SingleOrDefault();
var userinfo = new UserInfoViewModel
{
UserName = User.Identity.GetUserName(),
FirstName = firstname.Value.ToString(),
LastName = lastname.Value.ToString(),
UserApproved = Convert.ToBoolean(IsApproved.Value.ToString()),
HasRegistered = externalLogin == null,
LoginProvider = externalLogin != null ? externalLogin.LoginProvider : null
};
return userinfo;
}
From the client, this actin will be called through the token as a header.
Once we have got the information (is in Json string format) needs to serialize with the UserInfoViewModel class (user defined viewmodel is based on the info we require and send from webapi account) with javascript serializer
Using these viewmodel information, assign them to local storage and using (cookies for my case) as a identity at local
keep logout webapi too when ever you logs out from web app.
Please let me know if you need more info or code

How to develop user-authenticated REST service with Azure ACS

I'm developing a REST service that uses MS Azure Access Control Service for authentication. If the examples are any indication, the typical way to secure a REST service this way would be to provide a global username and pw, private key, or X.509 cert for the protected service. However, I want to use the passive user login mechanism on a mobile device with a flow more like the following:
Unauthenticated user attempts to access protected service from app
Mobile app redirects to browser app (or embedded browser)
User selects identity provider to use for login (facebook, google, etc.) from ACS login page
User enters credentials for identity provider
Browser redirects back to app
App somehow gets the SWT token to use with subsequent REST requests.
I'm stuck at about step 5--getting the SWT token, and the existing examples I've found don't seem to address this scenario. In addition, I'm actually trying to build a proof of concept with a desktop client in WPF, which may complicate things. Can anyone suggest a specific tutorial or a path to pursue that uses the per-user authentication vs. per-service? Thanks.
EDIT:
As I'm digging into this deeper, I've realized that the examples posted below (and most others) are based on OAuth WRAP, which has been deprecated in favor of OAuth 2.0. Can anyone suggest a more up to date reference? Googling has turned up http://blogs.msdn.com/b/adventurousidentity/archive/2011/09/18/acs-v2-oauth-2-0-delegation-support-explained.aspx and http://connect.microsoft.com/site1168/Downloads/DownloadDetails.aspx?DownloadID=32719 but they're not the most intuitive.
You should look into the ACS Windows Phone sample:
http://msdn.microsoft.com/en-us/library/gg983271.aspx
Here instead of using Silverlight you will be using WPF. Most of the code should be re-usable. Note that since you are using WPF you will need to register your own object for scripting e.g:
[ComVisibleAttribute(true)]
public class NotifyHandler
{
public void Notify(string notifyString)
{
// Here I have the token.
}
}
this.webBrowser1.ObjectForScripting = new NotifyHandler();
Update:
The sample above uses OAuth Wrap to contact the secured service. If you would like to use OAuth2 you should change the way the "Authorization" header set:
OAuth WRAP case:
WebClient client = new WebClient();
client.Headers["Authorization"] = "OAuth " + _rstrStore.SecurityToken;
OAuth2 case:
WebClient client = new WebClient();
client.Headers["Authorization"] = string.Format("OAuth2 access_token=\"{0}\"", token);
You can use the "Simple Service" sample as a guide to implement your token validation in your REST service:
http://msdn.microsoft.com/en-us/library/gg185911.aspx
Yet if you would like to implement a more complete sample you can look at how CustomerInformationService is protected in the CTP version 1.4:
https://connect.microsoft.com/site1168/Downloads/DownloadDetails.aspx?DownloadID=35417
Take a look at this one:
WPF Application With Live ID, Facebook, Google, Yahoo!, Open ID
http://social.technet.microsoft.com/wiki/contents/articles/4656.aspx

Resources