I have a public Microservice that I want to expose to the world. When creating a Microservice application we always get the question :
? (6/16) Which *type* of authentication would you like to use? (Use arrow keys)
❯ JWT authentication (stateless, with a token)
[BETA] Authentication with JHipster UAA server (the server must be generated separately)
But what about having a "No Authentication" option (like "No" registry or "No database") ? This would get rid of a few lines of code and Spring Security configuration.
WDYT ?
You can create your custom RestController and set a mapping different from /api/*** because it's only path prefixed by /api that are secure.
Related
I have a core hosted API which uses IdentityServer and issues JwtBearer tokens to my desktop based client. This is generally working and I can log in and use the application as expected.
However, when using Azure Deployment Slots I run into problems due to the Issuer validation.
When swapping slots, azure doesn't swap the running code, but rather just swaps the pointing urls so that a warmed up running app is ready to serve requests immediately. However, the Identity Server implemenation seems to keep a reference to the OLD slot URL and use this as part of the Issuer Validation.
This means that once the slots are swapped, not only are all the clients effectively logged out (which is bad enough), but then when the client logs in again the token that the Identity Server supplies isn't even valid becuase it's got the wrong URI for the issuer.
This results in the error:
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:
IdentityServerJwtBearer was not authenticated. Failure message:
IDX10205: Issuer validation failed. Issuer:
'https://my-app-name.azurewebsites.net'. Did not match:
validationParameters.ValidIssuer:
'https://my-app-name-deployment.azurewebsites.net' or
validationParameters.ValidIssuers: 'null'.
I have tried to disable Issuer Validation by doing this in the setup:
services.AddAuthentication(options =>
{
})
.AddCookie()
.AddJwtBearer(options =>
{
options.TokenValidationParameters.ValidateIssuer = false;
})
.AddIdentityServerJwt();
However this doesn't seem to make any difference. Am I setting this variable in the wrong place? Are there other settings that need to be also configured as well as this to bypass this check?
I have also tried setting the list of ValidIssuers to include both 'https://my-app-name.azurewebsites.net' and 'https://my-app-name-deployment.azurewebsites.net' in the hopes that either one would be accepted and allow tokens to be validated by either slot, but again this seems to make no difference.
Alternatively, Is there a way to pervent IdentityServer caching the Issuer Url - or a way to flush that cache without restarting the application? Currently once the slots are swapped the only way I can get the desktop application to access the API is to restart the API application and then log in again aftwards (just logging out and logging in still results in a token that the server cannot validate, even though the server just issued it).
I feel like I must be missing something glaringly obvious, but I can't see what it is...
To configure the IdentityServer JWT Bearer you can use a configure call:
services.Configure<JwtBearerOptions>(IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
options =>
{
options.TokenValidationParameters.ValidateIssuer = false;
});
This way it the ValidateIssuer flag is set on the IdentityServerJwt rather than the original code which set up a new JwtBearer which was entirely seperate from the IdentityServer one.
Once the configuration is being set on the correct service it is also possible to use the array of ValidIssuers to include the Asure Slot Urls that should be accepted.
I am new to Istio and I have learned a lot and applied to my project which consist of many Microservices. I am stuck in Authentication when it comes to using Istio
So the issue is this. Istio offers authentication which involves using Oauth google, Oauth or any other provider. and Once we do this, we can setup AuthPolicy and define which microservices we want it to apply to. I have attached my auth policy yaml and it works fine. Now may project at Job requires me to use custom auth also. In other words, I have one microservice which handles authentication. This auth microservice has three end points /login ,/singup, /logout and /auth. Normally, In my application, I would call /auth as a middleware to before I make any other call to make sure the user is logged in. /auth in my microservice reads jwt token I stored in a cookie when I logged in at a first place and check if it is valid. Now my question is how to add my custom authentication rather than using Oauth?. Now as you know auth policy.yaml I attached will trigger auth check at sidecar proxy level; so I don't need to direct my traffic to ingress gateway; that means my gateway takes care of mtls while sidecar takes care of jwt auth check. So how to plug in my custom auth in policy.yaml or another way such that "I don't need to redirect my all traffic to ingress gateway".
In short please help me with how to add my custom auth jwt check-in policy.yaml like in the picture or any other way and if required modify my auth [micro-service][1] code too. People suggest redirecting traffic to ingress gateway and add envoy filter code there which will redirect traffic to auth microservices. But I don't have to redirect my all calls to ingress gateway and run envoy filter there. I want to achieve what istio already doing by defining policy yaml and jwt auth check happens at sidecar proxy level suing policy.yaml; so we don't redirect traffic to ingress gateway.
Np: my all microservices are in ClusterIP and only my front end is exposed outside
Looking forward to your help/advice
Heres my code for auth policy.yaml
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: reshub
spec:
targets:
- name: hotelservice // auth check when ever call is made to this microservice
peers:
- mtls: {}
origins:
- jwt:
issuer: "https://rshub.auth0.com/"
jwksUri: "https://rshub.auth0.com/.well-known/jwks.json"
principalBinding: USE_ORIGIN
here's my code for auth microservice just to show you my current log of checking jwt
#app.route('/auth/varifyLoggedInUser',methods=['POST'])
def varifyLoggedInUser():
isAuthenticated = False
users = mongo.db.users
c = request.cookies.get('token')
token = request.get_json()['cookie']
print(token)
if token:
decoded_token = decode_token(token)
user_identity =decoded_token['identity']['email']
user = users.find_one({'email': user_identity,'token':token})
if user:
isAuthenticated = True
return jsonify({'isAuthenticated' : isAuthenticated,'token':c})
Try the AuthService project here which seems to aim to improve this area of Istio, which is at the moment pretty deficient IMO:
https://github.com/istio-ecosystem/authservice
I think the Istio docs imply that it supports more than it really does - Istio will accept and validate JWT tokens for authorization but it provides nothing in the way of authentication.
We have a SaaS web app and our clients are requiring SSO authentication for each of them. We are using AzureADB2C and it works great, but now are looking at adding SSO.
I put in the SSO setup into the B2C tenet and it works great, but really messed up our login screen with a "MyCompanySSO" button to log in with, on our customer-facing login screen.
So now my idea is to have a separate user flow that handles each SSO setup. Starting with us. We'd go to MyCompany.OurSaaSApp.us and that'd forward them directly to the user flow endpoint and prompt them to login with their SSO account (AzureAD).
This all seems to try to work, but I'm getting these errors within the AzureADB2C middleware:
Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler:Warning: .AspNetCore.Correlation. state property not found.
Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler:Information: Error from RemoteAuthentication: Correlation failed..
Then I get pumped out onto a error page and the login fails.
So 2 things...
1.) Am I going in the right direction knowing what we're wanting to accomplish
2.) What do we need to do to resolve this?
Thanks everyone for the help, it's been greatly appreciated.
(note:)
Just to reiterate. The SSO works properly when the custom identity provider is attached to the existing SignUpOrIn UserFlow I have configured in the app. I'm only getting this error when I try to use another UserFlow that I want to use specifically for this SSO.
I'm not sure about that specific error, although "state" parameter is a parameter that your app sends in the request that will be returned in the token for correlation purposes.
Using and different policy for each federation sounds like the right approach, but if you are doing from a single instance of your app, you'll need to modify the OIDC protocol message with the correct authority (ie policy) on redirect.
In your OIDC middleware configuration, set up a handler for the RedirectToIdentityProvider notification. Then handle it with something like:
private Task OnRedirectToIdentityProvider(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
//var policy = notification.OwinContext.Get<string>("Policy");
var tenantSegment = notification.Request.Path.Value.Split(new char [] { '/'}, StringSplitOptions.RemoveEmptyEntries)[0];
if (!string.IsNullOrEmpty(tenantSegment) && !tenantSegment.Equals(DefaultPolicy))
{
notification.ProtocolMessage.IssuerAddress = notification.ProtocolMessage.IssuerAddress.ToLower().Replace(DefaultPolicy.ToLower(), $"B2C_1A_{tenantSegment.ToLower()}_SignUpSignInPolicy");
}
return Task.FromResult(0);
}
If you need to inject anything else tenant-related, that would be the place to do it.
I'am running a nodejs/express application as a backend solution for my current project. The application is using passport-jwt to secure some routes with JWT as header Authorization for a route, let's call this route secure-route. Now I'm running a second application which needs to access secure-route without the necessary Authorization header. The necessary Authorization header is generated by a login route after the user has authorized successfully.
The problem is, that I don't want to provide a (fake) jwt Authorization header (which shouldn't expire). The second application/server should access my first application with a more appropriate authorization strategy like basic-auth.
I thought about making secure-route private in another router module so I can access this private route by maybe rerouting.
So how can I make an express route private accessible ? Or is there a solution for authenticating a backend/server without affecting the current authentication strategy ?
EDIT :
both backends running on a serverless structure on AWS
Assuming this second application you mention is running either on the same server or on another server in the same network, then you can do the following:
Create a new web server on a non-standard port that is not accessible from the general internet (just a few lines of code with Express).
Run that new web server in the same nodejs process that your existing server with the secure-route is running on.
In that new server, create a route for the private access. In that private route, do not implement any access control.
Put the code for the route into a separately callable function.
When that new server route gets hit, call the same function that you use to implement the secure route in the other server.
Verify that there is no access to your second server's port from the internet (firewall settings).
You could also just take your one existing server and route and allow access without the authorization header only when accessed from a specific IP address where your other app is running.
If you can't use anything about the network topology of the server to securely identify your 2nd app when it makes a request, then you have to create a secret credential for it and use that credential (akin to an admin password or admin certificate). Or, switch to an architecture where you can use the network topology to identify the 2nd app.
You should make a middleware and use it like this
/Starting Point of the Project/
let CONGIG = require('./config');
let middleware = require('./middleware');
let app = express();
app.use(middleware.testFunction);
require('./route')(app);
'use strict';
let middleware = {
testFunction : function(req,res,next){
var condition = ''; /* now here you can write your logic on condition that when should be the condition be true and when it shoudld not be true based on the req.url , if the user is trying to access any public url you can simply allow the true part of the condition to run and if the person is accessing a private part of route then you can check for additional parameters in header and then set the condition true and if not you must send an error msg or a simple message as you are not allowed to access the private parts of the web application. */
if(condtion){
next();
} else {
res.send('error');
}
}
}
So by designing a middlware you can basically seperate the logic of private and public routes and on what condition a route is public or private in a seperate module that will deal with it , it is little bit difficult to understand but it is better to first filter out public and private route than latter checking . In this way on the very initial hit we can differentiate the private and public routes.
I have been playing around with the Azure SFTP connector for API Apps and Logic Apps (under the new preview site (portal.azure.com)) but have not had much luck getting it to work.
The Connector requires the following package settings to be set: ServerAddress, ServerPort, SSH Server HostKey, Root Folder, Accept Any SSH Server HostKey (bool), and Encrypt Cipher. It does not ask for a user name, and after activating the API app and attempting to use it I get the expected response of HTTP 400 with:
[
"User Name Value cannot be null, empty, or cannot contain only white-space characters."
]
The Swagger api definition does not define any way to pass in the username and I cannot see anyway to define it in the connector settings, does anyone know how to set the username?
You can configure the user and pass at the security component in your App API panel, select it an then you can set the user and password.
Check this url for more info: http://azure.microsoft.com/en-gb/documentation/articles/app-service-logic-connector-sftp/