How to send email id when calling identity server 4 to login - identityserver4

I have a angular application and identity server 4 application. I have a login page in angular app which have only user name and when user enters his username , i want to send this username to IDs 4 and based on his username i will ask him to login either using password or redirect to AZure AD (i have saved these settings in DB which mode he needs to login).
From angular we are only able to call this method this.oidcSecurityService.authorize();
Can anyone suggest the way to send the username to IS4 from angular application using the angular-auth-oidc-client library.

OpenID Connect authorization requests can include the username in the login_hint parameter. IdentityServer will then make that available to you via the IIdentityServerInteractionService.
Your client library should allow you to set this query string parameter for authorization requests.

Related

How to redirect to another application Single Sign On Identity Server 4 and logout

I have an application A and an application B both of which are Asp.Net MVC Core 2.2 which should behave as if they are a single application to the end user; I'm using SSO in Identity Server; and in order to share claims between them I have given them the same Authentication Cookie name, Application name and access to a shared data protection key location as per the instructions:
https://learn.microsoft.com/en-us/aspnet/core/security/cookie-sharing?view=aspnetcore-2.2
If I login to A and then Redirect to B I can see the claims as expected shared between the applications; however if I then logout from B the logoutId which is generated and sent to the Identity Server 4 has no knowledge of B.
If I give a different name for the Authentication Cookie then I cannot share the claims but after redirecting to B and then logout from B the logoutId which is generated works correctly.
If after redirecting to B then waiting for the login session to timeout and re-authenticating then logout the logout of B works correctly; and the logoutId which is generated and sent to Identity Server 4 has knowledge of both A and B.
I believe this is because after redirecting to B when the Authorize attribute triggers a check that the user is Authenticated; which the user is in Application A and this is 'mistaken' for being already Authenticated in B; as this is a SSO there is no reason to authenticate in B as if authentication was checked with the Identity Server 4 then the user would be authenticated; however since the authentication is not checked the knowledge that the user has redirected to B is not stored in the shared authentication cookie and thus on Sign-out the Identity Server 4 does not receive the correct logoutId.
What can I do to force Identity Server 4 to be notified and thus update the Shared Cookie after the redirect to Application B?
You should not use shared cookies between your Angular apps to achieve SSO behavior. Neither you should share claims between those apps. In OAuth, the SSO is achieved by having a single authority uri (your Identity Server 4) that all your domain apps use to authenticate users, meaning that once user goes to application A and is redirected to login and completes login flow, the cookie is left on the on your Identity Server 4 app, and then once you redirect your application B it will see that it's not authenticated and redirect to the Identity Server 4 which will then use the cookie and automatically log the user in (can even skip consent page optionally).
Single sign out is a bit more difficult and is achieved by using SignOutIFrame on your Identity Server 4. In a nutshell, the idea is that once you initiate the logout flow from one of your apps, after the user successfully logs out from the Identity Server 4 app, the rendering of this SignOutIFrame causes all other clients to optionally participate in the logout flow and clear the session, etc. for a given user. More info can be found here.

Add a temporary claim From Account Controller Login Method

Using Identity Server Aspnet Identity Quickstart Link, with EntityFramework for Persistent Storage.
I added a dropdown list to login page along with username and password fields. The user is supposed to select a value from dropdown list while logging into the Identityserver.
How can I add the selected value of the dropdown list as a claim for that particular session and send it back to clients along with requested claims?
My clients are MVC application which communicates with Identity Server using Hybrid Flow.
IdentityServer v2.0.2
MVC Client : AspNet Core 2.0.0
Store the value in the signin cookie when calling SignInAsync
Return the value as a claim in the IProfileService

Identity server 4 and Angular app authenticate to achieve forever lasting session

Current structure:
I have angular app as Client, API as data source and Identity server as Identity source. In angular I authenticate user against identity server and use returned token to authorize user against API. Which Grant type should I use to authenticate my angular app user against identity server?
According to http://docs.identityserver.io/en/release/topics/grant_types.html, I should use Implicit grant type.
Problem is that with Implicit grant type there are no refresh tokens. So my question is, how should I keep my user session alive in angular app (access token valid) ? - without asking user to authenticate himself after every time access token gets expired.
My goal is to have session alive (token valid) until its killed by user (logged out)
Yes, the Implicit flow is the one I would use. If your authentication provider supports sessions, you can use OpenID Connect to get new tokens without user interaction. Before the token expiration, create an authentication request (/auth endpoint) in a hidden iframe with prompt=none URL parameter (id_token_hint=... parameter should be present too according to the OpenID Connect RFC). If the user session is open, you will get new tokens, otherwise error is returned (user interaction required).
There is the OpenID Connect Session Management RFC that describes this process and more (single sign on).

how to integrate regular username/password login with 3rd party social login for a Spring Boot + Angular single page web app?

I have a Angular + Spring boot single page web app. The server also acts as an Auth Server which issues tokens for the angular app to use to make Restful API calls.
My old login flow uses a grant_type=password POST call to the /oauth/token endpoint to get a Bearer token. And all further API calls on behalf of the user will include the Bearer token as the "Authorization" http header.
Now I need to integrate social login (facebook, twitter, etc.), which means I don't have username/password to generate tokens so I'm not sure how to make it work.
I have been using the following two tutorials as my template:
Spring Security and Angular JS
Spring Boot and OAuth
In the first tutorial's oauth-vanilla example, the username passwork login flow brings up the authorization page. But I'd like to have the traditional username/password form login experience (log user in directly instead of showing the Authorization page).
In the second tutorial, after facebook login, I'd like to use the facebook id to look up my internal user database and create a new user if not exist and logs him in as the user. And use the internal db user's identity and authorities to authorize future API calls to my API server.
I have a stripped down sample at at
https://github.com/dingquan/spring-angular-oauth
I can make POST calls to /oauth/token endpoint and use the returned token to make further api calls to my protected /api/blogs endpoint. But I haven't figure out how to make the following things work:
Username/password login that will create a session cookie so I don't need to send the Authorization bearer token for future API calls to the resource endpoint
After facebook login (the facebook login link is under the username/password login form), calls to my endpoint still fails with 401 error (I have a "test" button that makes a get call to /api/blogs, you can click on it to see the behavior). So what am I missing to make the API call succeed?
=== UPDATE ===
Just to clarify. Here are the goals I'm trying to achieve:
multiple ways of authentication (traditional username/password, third party oauth login such as facebook, possibly cellphone number + SMS code in the future)
we do need our own user model backed by DB to store other user attributes, pure social login is not enough
social login needs to be implicit. Meaning user should not be required to create a user account in our system manually once they login through a 3rd party (facebook, etc.). We're not just grabbing users' social profile data to pre-populate the registration form. We want to create new DB users automatically behind the scene if no existing db user is associated with the given external social account. i.e. if user is logged in through facebook, they don't need to enter username/password. Authentication through facebook will automatically log the user into our system as well and user should be able to access restricted resources after facebook login.
There's some confusion that I might be asking people to put their facebook username/password in a login form hosted by my app and I'll login facebook on behalf of the user. That's not what I was asking for.
You don't need such a complicated configuration. Add #EnableOAuth2Sso to your MainConfiguration and set appropriate application properties.
Here is what I have done in order to use Facebook as a authorization server.
a) Remove clientId and authServer from UserServiceImpl. Otherwise you'll be forced to configure an authorization server that is not needed.
b) Remove AuthorizationServerConfiguration completely.
c) Add #EnableWebSecurity and #EnableOAuth2Sso to your MainConfiguration.
d) Change MainConfiguration::configure to
http
.logout().logoutSuccessUrl("/").permitAll().and()
.authorizeRequests().antMatchers("/", "/login", "/home.html").permitAll()
.anyRequest().authenticated()
.and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
e) Delete everything else except nested class AuthenticationSecurity from MainConfiguration.
f) Change ResourceServerConfiguration::configure(HttpSecurity) to
http.antMatcher("/api/**").authorizeRequests().anyRequest().authenticated();
f) Remove attribute tokenStore and method ResourceServerConfiguration::configure(ResourceServerSecurityConfigurer) from ResourceServerConfiguration.
g) Remove configuration block security and facebook from application.yml. Instead add this
security:
oauth2:
client:
client-id: <CLIENT_ID>
token-name: oauth_token
authentication-scheme: query
client-authentication-scheme: form
access-token-uri: https://graph.facebook.com/oauth/access_token
user-authorization-uri: https://www.facebook.com/dialog/oauth
resource:
user-info-uri: https://graph.facebook.com/me
client-id: <CLIENT_ID>
client-secret: <CLIENT_SECRET>
token-type: code
h) In index.html change login to login.
i) Replace the content of hello.js with this one.
But I'd like to have the traditional username/password form login experience (log user in directly instead of showing the Authorization page).
I would never use a site that requires my credentials without redirecting me to the origin! I don't know you and you are under suspicion being a phishing site.
You should really reconsider your decision.
Btw, I created a pull request with these changes.

How to create email verification on Firebase simple login

In angularfire seed project, there is an account registration process using email and password. But how can we verify that the email is not fake? I mean it is without server code, just client code.
Store a token in the database send the same token via e-mail to the client ask them to click a link in the e-mail that passes the token back to a page which marks their e-mail as verified.
You can angularjs-fire seed project at this link angularfire_seed_with_reg_confirmation. Some explanation of it here email verification using angularjs+firebase Below is the quote from its readme:
It is AngularJS seed with Firebase backend and a feature for account
registration confirmation via email. This feature can be used as an
alternative for account activation. It is a clone of AngularFire Seed
with additional feature above and also login feature vial social login
ie login with Facebook, Twitter, and Google.
The account registration differs significantly from the original seed.
We can register for an account just by supplying an email and then
we'll get a confirmation email about our temporary random password.
The password is recommended to be changed to a memorable one and at
the same time it must also be strong and secure.

Resources