Silverlight ActiveDirectore Autentification - silverlight

How i can get Current User. And how i can validate user via Active Directory by user and pass.

You should use ASP.NET authentification to achieve this. In order to implement this, I would strongly recommend you to use something as RIA Services, which contains all the plumbing required to enable ASP.NET authentification in a Silverlight App.
With ASP.NET auth enabled, you will be able to edit your config file to use a AD identity provider, as in any other ASP.NET web app.
More informations about the ActiveDirectoryMembershipProvider on MSDN

[OperationContract]
public string GetCurrentUserWindowsLogin()
{
return Environment.UserName;
}
[OperationContract()]
public User DoLogIn(string login, string password)
{
string userName = String.Format(#"ELEGION\{0}", login);
string SERVER = "LDAP://Caesar.elegion.local";
User user = null;
try
{
DirectoryEntry entry = new DirectoryEntry(SERVER, userName, password, AuthenticationTypes.ReadonlyServer);
object nativeObject = entry.NativeObject;
if (nativeObject != null)
{
HeRMeSSunRiseDBEntities ent = EntitySingleton.Entities;
user = ent.Users.Where(l => l.Login == login && l.IsDisabled == false).FirstOrDefault();
if (user != null)
{
user.ADObject = entry.Guid.ToString();
ent.SaveChanges();
return user;
}
}
}
catch (DirectoryServicesCOMException cex)
{
Debug.Write(cex.Message);
}
catch (Exception ex)
{
Debug.Write(ex.Message);
}
return user;}

Related

Graph API: Insufficient privileges to complete the operation

I have the following permissions on my registered Azure Function..
This azure function will work as web hook and called by some application/API
but when I try to get data
public async Task<string> FindUpnByEmail(string email)
{
if (string.IsNullOrEmpty(email)) return email;
try
{
var request = new RestRequest("users")
.AddQueryParameter("$filter", $"mail eq '{email}'")
.AddQueryParameter("$select", "userPrincipalName");
var rest = new RestClient(GraphUrl)
{
Authenticator = await GetAuthenticator(),
};
var response = await rest.ExecuteGetAsync(request);
var userResponse = JsonConvert.DeserializeObject<ODataResponse<User>>(response.Content);
return userResponse.Value.Length > 0 ? userResponse.Value[0].UserPrincipalName : email;
}
catch (Exception ex)
{
return email;
}
}
I receive the following error:
Authorization_RequestDenied","message":"Insufficient privileges to
complete the operation.
Try to update the Admin consent to Yes for profile, Read Basic profile.
Or Add read write delegate permission and grant admin consent for that as well.

IdentityServer Refresh Extension Grant

I have implemented an extension grant in my Identity Server instance. The purpose of this is for a mobile app to switch contexts between an authenticated user and a public kiosk type device.
When the user enters this mode, I acquire a new token and include the proper grant type.
I used the IS documentation as a base. Nothing crazy going on here at all, I just add some additional claims to this token to be able to access things in the API the user may otherwise not be set up for.
public class KioskGrantValidator : IExtensionGrantValidator
{
private readonly ITokenValidator _validator;
public KioskGrantValidator(ITokenValidator validator)
{
_validator = validator;
}
public string GrantType => "kiosk";
public async Task ValidateAsync(ExtensionGrantValidationContext context)
{
var userToken = context.Request.Raw.Get("token");
if (string.IsNullOrEmpty(userToken))
{
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
return;
}
var result = await _validator.ValidateAccessTokenAsync(userToken);
if (result.IsError)
{
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
return;
}
// get user's identity
var sub = result.Claims.FirstOrDefault(c => c.Type == "sub").Value;
// I add some custom claims here
List<Claim> newClaims = new()
{
new Claim(ClaimTypes.Name, "kiosk")
}
context.Result = new GrantValidationResult(sub, GrantType, claims: newClaims);
return;
}
}
Now, the question is refreshing this token.
For this grant to work I'm passing in the access token, which expires, eventually causing the ValidateAccessTokenAsync to fail.
Wanted to see what the best way to refresh this token is? Currently the best way I have found is to refresh the original user access token when this one is about to expire, then get a second token with the new grant. This works, but seems maybe unnecessary.
Thanks for any input!

AspNet.Core Identity Authentification from WPF client

I've implemented asp.net core Identity authentifaiction and it's working fine with my web application. In the startup.cs file, I have the following:
services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
options.LoginPath = "/Identity/Account/Login";
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.SlidingExpiration = true;
});
And in the Login.chtml.cs, I've the the login method:
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true);
if (result.Succeeded)
{
//...
}
else
{
//....
}
}
return Page();
}
Now I'm putting in place a WPF client in which I want to authenticate my users using the AspNetCore.Identity login procedure. Any suggestion about how to proceed will be highly appreciated.
Finally, I decided to go with IdentityServer4 in order to have a centralized login and workflow for the WPF client and other clients that I may need later.

Login after signup in identity server4

I am trying to login user as soon as he/she registers.
below is the scenario
1)Registration page is not on identity server.
2)Post user details to Id server from UI for user creation.
3)On successful user creation login the user and redirect.
4)Trying to do it on native app.
I tried it with javascript app but redirection fails with 405 options call.
(tried to redirect to /connect/authorize)
on mobile app, don't want user to login again after signup for UX.
Has anyone implemented such behavior
tried following benfoster
Okay so finally i was able to get it working with authorization code flow
Whenever user signs up generate and store a otp against the newly created user.
send this otp in post response.
use this otp in acr_value e.g acr_values=otp:{{otpvalue}} un:{{username}}
client then redirects to /connect/authorize with the above acr_values
below is the identity server code which handles the otp flow
public class SignupFlowResponseGenerator : AuthorizeInteractionResponseGenerator
{
public readonly IHttpContextAccessor _httpContextAccessor;
public SignupFlowResponseGenerator(ISystemClock clock,
ILogger<AuthorizeInteractionResponseGenerator> logger,
IConsentService consent,
IProfileService profile,
IHttpContextAccessor httpContextAccessor)
: base(clock, logger, consent, profile)
{
_httpContextAccessor = httpContextAccessor;
}
public override async Task<InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
{
var processOtpRequest = true;
var isAuthenticated = _httpContextAccessor.HttpContext.User.Identity.IsAuthenticated;
// if user is already authenticated then no need to process otp request.
if (isAuthenticated)
{
processOtpRequest = false;
}
// here we only process only the request which have otp
var acrValues = request.GetAcrValues().ToList();
if (acrValues == null || acrValues.Count == 0)
{
processOtpRequest = false;
}
var otac = acrValues.FirstOrDefault(x => x.Contains("otp:"));
var un = acrValues.FirstOrDefault(x => x.Contains("un:"));
if (otac == null || un == null)
{
processOtpRequest = false;
}
if (processOtpRequest)
{
var otp = otac.Split(':')[1];
var username = un.Split(':')[1];
// your logic to get and check opt against the user
// if valid then
if (otp == { { otp from db for user} })
{
// mark the otp as expired so that it cannot be used again.
var claimPrincipal = {{build your principal}};
request.Subject = claimPrincipal ;
await _httpContextAccessor.HttpContext.SignInAsync({{your auth scheme}}, claimPrincipal , null);
return new InteractionResponse
{
IsLogin = false, // as login is false it will not redirect to login page but will give the authorization code
IsConsent = false
};
}
}
return await base.ProcessInteractionAsync(request, consent);
}
}
dont forget to add the following code in startup
services.AddIdentityServer().AddAuthorizeInteractionResponseGenerator<SignupFlowResponseGenerator>()
You can do that by using IdentityServerTools class that IdentityServer4 provide to help issuing a JWT token For a Client OR a User (in your case)
So after the user signs up, you already have all claims needed for generating the token for the user:
including but not limited to: userid, clientid , roles, claims, auth_time, aud, scope.
You most probably need refresh token if you use hybrid flow which is the most suitable one for mobile apps.
In the following example, I am assuming you are using ASP.NET Identity for Users. The IdentityServer4 Code is still applicable regardless what you are using for users management.
public Constructor( UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IClientStore clientStore,
IdentityServerTools identityServerTools,
IRefreshTokenService refreshTokenService)
{// minimized for clarity}
public async Task GenerateToken(ApplicationUser user
)
{
var principal = await _signInManager.CreateUserPrincipalAsync(user);
var claims = new List<Claim>(principal.Claims);
var client = await clientStore.FindClientByIdAsync("client_Id");
// here you should add all additional claims like clientid , aud , scope, auth_time coming from client info
// add client id
claims.Add(new Claim("client_id", client.ClientId));
// add authtime
claims.Add(new Claim("auth_time", $"{(Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds}"));
// add audiences
var audiences = client.AllowedScopes.Where(s => s != "offline_access" && s != "openid" && s != "profile");
foreach (var audValue in audiences)
{
claims.Add(new Claim("aud", audValue));
}
// add /resources to aud so the client can get user profile info.
var IdentityServiceSettings = _configuration.GetSection("IdentityService").Get<IdentityServiceConsumeSettings>();
claims.Add(new Claim("aud", $"{IdentityServiceUrl}/resources"));
//scopes for the the what cook user
foreach (var scopeValue in client.AllowedScopes)
{
claims.Add(new Claim("scope", scopeValue));
}
//claims.Add(new Claim("scope", ""));
claims.Add(new Claim("idp", "local"));
var accesstoken = identityServerTools.IssueJwtAsync(100, claims);
var t = new Token
{
ClientId = "client_id",
Claims = claims
};
var refereshToken = refreshTokenService.CreateRefreshTokenAsync(principal, t, client);
}
This is just a code snippet that needs some changes according to your case

Cannot open database "Auth" requested by the login. The login failed.Login failed for user 'ServerName'

I am developing an application in .net Core 2.1, where I apply the authentication by aspnet identity users. The database is on a server and my program in .net core is on another server with IIS. My program works correctly locally but when I deploy it to my server and try to access one of my methods to perform the login I get the following error:
Can not open database "Auth" requested by the login. The login failed.Login failed for user '[NAME-OF-SERVER-WITH-IIS]'.
The weird thing is that in my connection string I specified that the user that I was connecting to would be "sa".
Startup.cs - ConfigureServices method
public void ConfigureServices(IServiceCollection services)
{
String con = "Data Source=<Servername>;Initial Catalog=Auth;Persist Security Info=True;User ID=sa;Password=<Password>;Trusted_Connection=True;MultipleActiveResultSets=true";
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(con,
b => b.MigrationsAssembly("Auth")));
...
}
AuthController.cs - Login method
[HttpPost("Login")]
public async Task<IActionResult> Login([FromBody]CredentialsViewModel credentials)
{
try
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
var identity = await GetClaimsIdentity(credentials.UserName, credentials.Password);
if (identity == null)
return BadRequest(Errors.AddErrorToModelState("login_failure", "Invalid username or password.", ModelState));
var jwt = await Tokens.GenerateJwt(identity, jwtFactory, credentials.UserName, jwtOptions, new JsonSerializerSettings { Formatting = Formatting.Indented });
return new OkObjectResult(jwt);
}
catch (Exception e)
{
return new OkObjectResult(e.Message);
}
}

Resources