authenticate using google and call remote api
Closed this issue · 5 comments
Which version of Duende BFF are you using?
2.2.0
Which version of .NET are you using?
net 8.0
Describe the Howto question
In BFF, we want authenticate against google, add scopes and roles in the access token and use this access token to authenticate and authorize to our backend apis.
We used this code to get the token:
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "https://localhost:5001"; // builder.Configuration["ServiceUrls:IdentityServerAuthority"];
options.ClientId = "bff";
options.ClientSecret = "The Super Secret Edited";
options.ResponseType = "code";
//options.Scope.Clear(); // Calling Clear Removes openid and profile
//options.Scope.Add("openid");
//options.Scope.Add("profile");
options.Scope.Add("api");
options.Scope.Add("offline_access");
options.Scope.Add("email");
options.Scope.Add(IdentityServerConstants.LocalApi.ScopeName);
options.SaveTokens = true;
options.MapInboundClaims = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.TokenValidationParameters.NameClaimType = "name";
options.TokenValidationParameters.RoleClaimType = "role";
options.ClaimActions.MapJsonKey("role", "role");
options.DisableTelemetry = true;
});
We used this code for connecting to the backend:
app.MapRemoteBffApiEndpoint("/remote/user-token", "https://localhost:6001")
.RequireAccessToken(Duende.Bff.TokenType.User);
scenario:
2 users login to google and are provisioned on the fly.
user 1 gets admin role
user 2 gets viewerrole
Obviously, the 2 users must get different access to the backend.
To Reproduce
Used and merged 2 samples:
Samples-main\IdentityServer\v7\BFF\TokenExchange and
Samples-main\IdentityServer\v7\BFF\JsBffSample
If we run Token Exchange and login with user alice using her username/password, it works: in the backend, we are alice.
If we run JsBffSample and authenticate using Google, in the front we are the Google user (email and name are correct, role is administrator.) But when we call the backend, in the backend we are client ID bff (with google sub), we are not anymore the user.
Email, name and scopes and roles that we have added are lost.
Expected behavior
We want to authenticate to Google, add scopes and roles in the access token and use it to get different permissions in the backend.
For example:
user 1:
Name : Alice
Email : alice@gmail.com
TenantID : ABC123
Role: Administrator
user 2:
Name : Bob
Email : bob@gmail.com
TenantID : ABC123
Role: Viewer
when authenticating to google, In the backend, in the controller, it crashes here: Name is not anymore in the token.
`
[ [HttpGet("{**catch-all}")]
public IActionResult Get()
{
string message;
var sub = User.FindFirst("sub");
if (!User.Identity.IsAuthenticated)
{
message = "Hello, anonymous caller";
}
else if (sub != null)
{
**var userName = User.FindFirst("name");** // It crashes here, name is not anymore in token.
message = $"Hello user, {userName.Value}";
}
else
{
var client = User.FindFirst("client_id");
message = $"Hello client, {client.Value}";
}
var response = new
{
path = Request.Path.Value,
message = message,
time = DateTime.UtcNow.ToString(),
headers = Request.Headers
};
return Ok(response);
}
}`
The identity provider needs to be configured to include the needed claims in the access token. Assuming you're using IdentityServer, user claims can be added to access tokens by configuring the ApiScope like this:
public static IEnumerable<ApiScope> ApiScopes =>
new ApiScope[]
{
new ApiScope("scope1") { UserClaims = ["role"] },
...
Or use the equivalent database table if your configuration is in a database.
You can also set user claims on the ApiResource level.
@edreux Did this solve it for you? If so I'd like to close this issue.
you can close this issue, we've abandoned this solution.