Post Identity Server 4 Registration - identityserver4

I have identity server 4 setup and my asp net core app working with it. If you hit a secure endpoint it redirects to Identity Server and you can login. Once you login it then redirects back to the url you were originally trying to access. What I would like to do is check that you have registered in my database before you get redirected. I thought that I could change 'RedirectUris' to a url of my choice but when I do that it has no effect. A breakpoint on that end point is never hit. What do I need to do in order to setup a post identity server login registration screen?
Is this the right way of doing it?
Thanks
Michael

If I understand your problem correctly, you want to get the user details in your application.
IdentityToken contains user name if you include Name scope.
If it is a web application then you may find the name on ((System.Security.Claims.ClaimsIdentity)User.Identity)
You can also add claims as you need, like userid, role etc
Comment
should each client have to 'register' a user with my api specifically?
What's the norm?
Depends on your requirements and what you are requesting for. On my case user must have allowed scope to access the api

Related

How to communicate securely to an Database with electron?

I am creating an electron application that connects to an Database and do POST and GET requests to retrieve and insert data into it, the problem is that in the code i have defined my database uri ( im using mongodb)
const uri = "mongodb+srv://<myusesrname>:<mypassword>#cluster0.wqbiu.mongodb.net/query?retryWrites=true&w=majority"
like in the example above, but if i pack my electron app the connection to the database as well as the credentials its visible if someone unpacks the app.asar file and look in the server.js file how i can solve this problem? i dont want any security breaches neither for me or the people that will be using my application, thanks in advance for any answer :)
An application that requires a secure connection to something cannot afford to have any username's or password's hardcoded into its code.
Instead, a procedure of authentication and authorisation is utilised.
Authentication is used to verify the user. IE: They are who they say they are, often achieved via the use of some type of login form.
Authorisation is used to verify the logged-in user is allowed to access the requested resource. EG: Is this user allowed to retrieve a list of all users email addresses from the database.
As a rough guide, a user will login with their username and password. You could use OpenID as well here if you wanted. Once the user is 'logged-in' you could set a cookie or session and save the session id in the DB against the user. Of course, all of this is done over HTTPS.
There are various ways to control the validity of the session such as but not limited to refreshing the expiration date / time every time the user hits the server, auto timeout if the user has not interacted with the server for more than X minutes, etc.
In your app, the user could try and interact with the database at any time, but if the user is not logged in, the server could return the appropriate response and prompt the user to login. Some form of API here is really the way to go.
If the user is logged in then then next step is to authorise the users request, ensuring they are allowed to perform what they are asking before sending a response back. If they are not authorised to access the resource (EG: Edit another user’s post) then an appropriate response is returned indicating so.
As you can see, securing your app will take some work but the result of not doing so could be devastating to you and your users.

Sitecore - How to get User ID if the user was logged in using external identity provider (Salesforce SSO)

I have a little bit of problem with the authentication on Sitecore website. Basically there is a button on the navbar, and when user clicks on the button, it redirects the same user to Salesforce to log in (Implementation of SSO). Basically I am using Salesforce as a identity provider and Sitecore Website as a service provider. Now I have a question? When user is logged, how can I get the ID of that user.
Do users in Sitecore User Manager have the same ID as the users in Salesforce, or I can just get a email to identify the user?
P.S: Sorry if this is a really stupid question, but I am a begineer when it comes to making Sitecore websites and the SAML SSO. Thank you in advance
Stop with the Sitecore and Salesforce for a second, you'll need to cover some basics and click through the login process manually before you automate it.
You probably are using a "connected app" in Salesforce that includes OAuth2 config (consumer key also known as client id; a secret; a list of scopes telling what this app is allowed to do on behalf of this SF user; a list of allowed urls that can login using this consumer key and secret. Etc.) It might even have something about Canvas Apps at bottom of the page.
Next would be - who's logging in. A core Salesforce user or do you have Partner Community, Customer Community (recently rebranded to "Digital Experiences").
Open incognito window and go to https://openidconnect.herokuapp.com/
For login host leave as is if you have production user or test.salesforce.com if you go from sandbox (you can also use branded urls, mycompany--dev.my.salesforce.com etc). If you have a community user you'll have to change the url to whatever is the community base url, like https://dev-mycompany.cs123.force.com/mycommunity
Don't change anything else, click next, next, next. This will take you through OAuth2 "web server flow" (one of many ways to log in). You type the username/password to SF screen and go back to that herokuapp with "authorisation code". The app has few minutes to swap that code for actual final "access token" and couple other pieces of info. Final step in this wizard calls OpenId "userinfo" - returning some info about the user that logged in. That's where you could pull the email if needed (and if there are extra fields you'd like SF to return in this process that's configurable too)
Close that browser window. Check the "connected app" in SF. Open new incognito window, do same thing but this time put your url, consumer key and secret (you might have to edit the app in SF first to allow callbacks to https://openidconnect.herokuapp.com/callback).
So now you should have rough idea about whole login process. Your sitecore app probably does same thing, receives authorisation code and exchanges it for final token. At that point you have valid SF session ID you could use to call that "userinfo", run queries (if the app allowes API access, check the "scopes") etc.
I doubt the Sitecore developer created it all by hand, you probably have some Spring stuff like spring.security.oauth2.client... My Java days are long gone but if you get better at manual click-click-click through the flow you should be able to follow existing code?
It's a big topic and there are other ways to do it (other OAuth flows, sending info about the current user when you have external page embedded in SF as iframe, you'd need to read about "canvas apps")... but that's best guess based on info you provided. You might want to check some trailhead courses too like https://trailhead.salesforce.com/content/learn/projects/build-a-connected-app-for-api-integration/implement-the-oauth-20-web-server-authentication-flow
https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_oauth_and_connected_apps.htm
https://developer.salesforce.com/docs/atlas.en-us.api_streaming.meta/api_streaming/code_sample_auth_oauth.htm (Java but very hand-crafted raw HTTP, probably that Spring security is better)

How to access multiple salesforce orgs with same connected app

I am trying to access the multiple communities in multiple salesforce sites with same connected-app but could not.
For example: I have created the two salesforce sites A and B. And created connected-app in A. To access rest API of A, i could authenticate with connected-app in A, But how to connect with B with using the same client_secret and client_id by differs in user_name and password?
Or is there any way to connect with REST API with username and password as creds?
Example: There is community_A1, community_A2 in Site A and community_B1 , community_B2 in Site B.
I need to access communities in both the Sites
This should work out of the box, what errors you're getting?
You can have 1 set of consumer key and secret and (if admin in target org didn't block it) you could use this to login to any SF in the world, sandbox or production, core SF or community.
Imagine being a developer of mobile app that pulls data from salesforce. You'd want to have just 1 pair of keys, not install separate key for every org people might install your app...
All org-specific stuff you need is username, password and login url. For community the login url will look like https://sandboxName-MyDomain.cs123.force.com/communityName
Once you have that, you can inspect all the OAuth2 stuff at https://sandboxName-MyDomain.cs123.force.com/communityName/.well-known/openid-configuration
Have you played with https://openidconnect.herokuapp.com/ ?
Paste your community url, for now keep the client and secret as is, click next. Login to community and keep clicking next. It should work fine and at the end - give you access_token / session id.
Now close this browser completely / open new incognito window and do it again. This time give your login url but also client and secret. Next, Next... Check the user's login history, it should mention your connected app now.
Now close this and do it last time, with the other community's login url and another user's credentials but still with your client and secret.
is there any way to connect with REST API with username and password
as creds?
Not for community. Internal users can get access in one go with https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_username_password_flow.htm&type=5 but community/experience users need this interactive login, there has to be a human consent / password typing step. And anyway it's not very secure flow. "Experience Cloud sites don’t support the OAuth 2.0 username-password flow."
In a pinch you could try the SOAP API's login method but from what I remember you may need to pass the community's Id in the message then
Connected-app is global metadata in salesforce. Once we create a connected-app in one org, then can access any salesforce site with the same client_id,client_secret, unless the admin has blocked the access.
I needed to add the custom profile into the community members to allow the access to the community via API (Community workspace -> administration -> members -> profiles.)

Single Page Application login with Spring and AngularJS

I'am creating application which can be used by unknown and logged in users. Only difference is that logged in user can use some additional functions like saving its content in database.
All communication is based on ajax calls, so what I need is to deny access to some controller functions (end points) in backend for unknown users and on the client side I need to know that it is in logged in state to set this extra functions active. Only one page, login form should be in dialog. I'm little bit confused, because standard Spring Security aproach doesn't fit this case. I was reading this tutorial but I cant't fully understand it.
First: What Principal object does? They send credentials to this endpoint on submit with login() function but where is handled password check? What if I have my users in database?
Second Is it possible to write this configuration in XML style? I guess that it can be done with <intercept-url/> in spring-security.xml file.
Principal Object
The Principal Object is used to be able to get basic information about a user that is attempting to login when using automatic server authentication (i.e. LDAP). However, you will only be able to get a username from the principal object. With a server JBoss/WildFly, for example, you can link the server to Active Directory to allow Microsoft Windows to authenticate users.
Simple Solution
First, Spring Security will add additional complexity to your application where it doesn't sound like you are trying to do that. Instead, use a simple Servlet Filter. If you are using LDAP on a JBoss/WildFly sever, you can make a POST to j_security_check and the server will send the request to the filter if correct credentials are provided. Inside the filter, you may use the getName() function of the Principal object to get the username so that you may store it in the user's session. However, if you are not using LDAP, you may make a simple POST to a Java Servlet or Spring Controller (with an #RequestMapping) to attempt to login the user and store the user's information in the session.
At this point, you can filter out what URLs you will allow users to see. For example, the URL that contains /administrator/some/other/stuff.jsp could be restricted if the URL contains the word "administrator" in the first directory of the URL.

Azure B2C Issues and Questions

I've been working with the Azure B2C for a couple of days now and have a few issues and questions:
Url that it creates to redirect for login is formed incorrectly. It contains a question mark twice - after the url, and again after the profile name. This causes a 404 not found error every time you login, log out, etc. For example, the URL it tries to redirect to for login looks like this: https://login.microsoftonline.com/samlmanbc.onmicrosoft.com/oauth2/v2.0/authorize?p=b2c_1_firstdemoprofile?client_id=08fcblahblah. You'll notice a second question mark after the profile name, and that's what breaks it.
If I fix that and try and log in, it doesn't recognize the username / password of my account that's a global admin. It DOES recognize the username / password of a new user I created locally in the directory.
In the OnRedirectToIdentityProvider method, when the request type is authentication, the AuthenticationResponseChallenge is null, which makes this call fail:
OpenIdConnectConfiguration config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None, notification.OwinContext.Authentication.AuthenticationResponseChallenge.Properties.Dictionary[Startup.PolicyKey]);
I worked around this by using the static string SignInPolicyId for the second parameter. That works fine when an account already exists, but if it doesn't then Azure fails at login and says an account doesn't exist for the user. So what is the right value to use there, and/or how does one initialize it so it isn't null?
The type of a claim that was added to a profile is preceded with "extension_"; is that always going to be true or just for now? For example, I added a property called "favoriteTeam", but the claim type for it is "extension_favoriteTeam".
When you use FaceBook as an identity provider, is there any way to pass along the Facebook access token claim (http://www.facebook.com/claims/AccessToken)? This was useful when using ACS with Facebook because your app can then use that token to make additional calls to Facebook to get data from it.
In relation to issue 1 - I updated my reference Microsoft.IdentityModel.Protocol.Extensions to v1.0.2.206221351 and it started working. I made some updates to other references before this, so if the first one doesn't work, try updating more assemblies from nuget.
This is as expected. A page that signs in "local account" users will not sign in your work or school account (in this case, the global admin user).
Always going to be true. We will be cleaning up the Admin UX to make this more clear.
This is on our roadmap. No ETA as yet.

Resources