How do you add Identity server 4.0 as an external provider? - asp.net-core

It looks like all of the sources talk about adding external providers INTO Identity Server 4, not using Identity Server 4 AS an external provider.
My startup.cs has this line for Facebook authentication:
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddFacebook(facebookOptions =>
{
facebookOptions.AppId = "<appId>";
facebookOptions.AppSecret = "<appSecret>";
facebookOptions.SaveTokens = true;
})
I have a button on my login page:
<a class="btn btn-primary"
asp-action="ExternalLogin"
asp-route-provider="Facebook"
asp-route-returnUrl="">
Facebook
</a>
Which leads to:
[HttpPost]
[HttpGet]
[AllowAnonymous]
public IActionResult ExternalLogin(string provider, string returnUrl = null)
{
// Request a redirect to the external login provider.
var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl });
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return Challenge(properties, provider);
}
Which all works.
I also have an Identity Server 4.0 server setup and I would like to use it as just another external provider.
services
.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddFacebook(facebookOptions =>
{
facebookOptions.AppId = "<appId>";
facebookOptions.AppSecret = "<appSecret>";
facebookOptions.SaveTokens = true;
})
.AddIdentityServer(identityServerOptions=> //Doesn't exist? or Does it?
{
identityServerOptions.AppId = "<appId>";
identityServerOptions.AppSecret = "<appSecret>";
identityServerOptions.SaveTokens = true;
})
How do I add identity server as an external auth provider?
**UPDATE: **
From This site
#if (Model.ExternalProviders.Any())
{
<div class="row">
<div class="panel-body">
<ul class="list-inline">
#foreach (var provider in Model.ExternalProviders)
{
<li>
<a class="btn btn-default"
asp-action="ExternalLogin"
asp-route-provider="#provider.AuthenticationScheme"
asp-route-returnUrl="#Model.ReturnUrl">
#provider.DisplayName
</a>
</li>
}
</ul>
</div>
</div>
}
It looks like the provider is the same as the Authentication Scheme

Identityserver is a certified OpenId Connect provider, so you can use just:
.AddOpenIdConnect(authenticationScheme, displayName, options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.Authority = "<base-path-of-your-external-IS>";
options.ClientSecret = "<appSecret>";
options.ClientId = "<appId>";
options.ResponseType = OpenIdConnectResponseType.Code;
options.SaveTokens = true;
}

Related

Change Default Page in Web API project .net core 6 MVC

I have ASP.net core **WebAPI ** project after that I create Scaffolded item witch Identity inside this project. How can I change Default page to Identity/page/login.cshtml instead of ~/swagger/index.html
Thanks
change default page from ~/swagger/index.html to Identity/page/login.cshtml
Thanks
my Code here
AppUser.cs
public class AppUser: IdentityUser <int>
{
public string FullName { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateModified { get; set; }
}
program.cs
builder.Services.ConfigureApplicationCookie(options =>
{
options.LoginPath = $"/Identity/Account/Login";
options.LogoutPath = $"/Identity/Account/Logout";
options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});
AppDbContext.cs
public class AppDbContext : IdentityDbContext<AppUser, IdentityRole<int>, int>
{
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options)
{
}
...........................................
}
_LoginPartial.cshtml
#using Claim.Data.Entities
#using Microsoft.AspNetCore.Identity
#inject SignInManager<AppUser> SignInManager
#inject UserManager<AppUser> UserManager
When I Test to click to Login to go to Login Page
error:
InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Identity.SignInManager`1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'XXXXXXX.Areas.Identity.Pages.Account.LoginModel'.
hi have fixed the problem. I have to change the Login.cshtmal.sc file.
However I got problem Authentication, cannot login
SignInManager.IsSignedIn(User) <- return claims = 0
_loginPatial.cshtml
#using Microsoft.AspNetCore.Identity
#inject SignInManager<IdentityUser> SignInManager
#inject UserManager<IdentityUser> UserManager
<ul class="navbar-nav">
#if (SignInManager.IsSignedIn(User))
{
<li class="nav-item">
<a id="manage" class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello #UserManager.GetUserName(User)!</a>
</li>
<li class="nav-item">
<form id="logoutForm" class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="#Url.Action("Index", "Home", new { area = "" })">
<button id="logout" type="submit" class="nav-link btn btn-link text-dark">Logout</button>
</form>
</li>
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" id="register" asp-area="Identity" asp-page="/Account/Register">Register</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" id="login" asp-area="Identity" asp-page="/Account/Login">Login</a>
</li>
}
</ul>
Login.cshtml.cs
if (result.Succeeded) <------ true
public async Task<IActionResult> OnPostAsync(string? returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return LocalRedirect(returnUrl);
}
..............................
program.cs
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddRazorPages();
builder.Services.AddDbContext<AppDbContext>(opt =>
{
opt.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
});
builder.Services.AddIdentity<IdentityUser, IdentityRole>().AddDefaultTokenProviders()
.AddEntityFrameworkStores<AppDbContext>();
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Constants.SecretKey)),
ValidateAudience = true,
ValidIssuer = Constants.Issuer,
ValidAudience = Constants.Audience,
RequireExpirationTime = true,
};
});
builder.Services.AddScoped<IUserClaimService, UserClaimServices>();
builder.Services.AddSingleton<IEmailSender, EmailSender>();
builder.Services.ConfigureApplicationCookie(options =>
{
options.LoginPath = $"/Identity/Account/Login";
options.LogoutPath = $"/Identity/Account/Logout";
options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});
//builder.Services.AddMvc().AddRazorPagesOptions(options =>
//{
// options.Conventions.AddAreaPageRoute("Identity", "/Account/Login", "");
//}
// );
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();

Controller not executing code (Blazor server-side)

My Goal Create a simple login form in order to authenticate and authorize the user in my Blazor Server-side app with Cookie Authentication.
My Issue Everything works... The EditForm passes the values to my Controller. The Controller validates the usercredentials. Then runs HttpContext.SignInAsync(claims) and returns Ok().
But the Cookie is not passed and the user is not Authenticate either.
What I have done
1. The EditForm, passes the userinputs to the DisplayLoginModel() on a ValidSubmit.
<div class="row">
<div class="col-8">
<EditForm Model="#userLogin" OnValidSubmit="OnValidLogin">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="mb-4 row">
<p class="col-sm-4 font-weight-bold">Email</p>
<div class="col-sm-8">
<InputText #bind-Value="userLogin.Email" class="form-control" />
</div>
</div>
<div class="mb-4 row">
<p class="col-sm-4 font-weight-bold">Password</p>
<div class="col-sm-8">
<InputText #bind-Value="userLogin.Password" class="form-control" />
</div>
</div>
<button class="btn btn-outline-primary col-sm-4" type="submit"><strong>Login EditForm</strong></button>
</EditForm>
</div>
</div>
2. The OnValidLogin Sends a request to the Form Controller
public DisplayLoginModel userLogin = new DisplayLoginModel();
private async Task OnValidLogin()
{
var requestMessage = new HttpRequestMessage()
{
Method = new HttpMethod("POST"),
RequestUri = new Uri("https://localhost:44370/Form"),
Content = JsonContent.Create(userLogin)
};
var client = httpfac.CreateClient();
var response = await client.SendAsync(requestMessage);
}
3. The Controller gets the user credentials from the displayloginModel and validets Ok().
[HttpPost]
public async Task<ActionResult> Post(DisplayLoginModel _userLogin)
{
if (_userLogin.Email == "this#Email.com")
{
ClaimsIdentity claimsIdentity = new ClaimsIdentity(new List<Claim>
{
new Claim(ClaimTypes.Role, "ActiveUser")
}, "auth");
ClaimsPrincipal claims = new ClaimsPrincipal(claimsIdentity);
await HttpContext.SignInAsync(claims);
return Ok();
}
else
{
return BadRequest();
}
}
4. Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient();
services.AddHttpContextAccessor();
services.AddAuthentication("Cookies").AddCookie(options =>
{
options.SlidingExpiration = true;
});
services.AddRazorPages();
services.AddServerSideBlazor();
}
And
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
Why is the Controller not signing the user in, what am I missing?
An image of the solution structure is seen right below:
Because Blazor Server uses websockets (Blazor circuits) to render the UI while on the controller, await HttpContext.SignInAsync(claims); returns a cookie header so the browser can be authorized on next page load. This means you are actually being authenticated server-side but not from the client-side as you have not reloaded the page context to update the cookies. There is a reason why the default Identity login uses MVC architecture for the authentication process. :)
My suggestion, switch to API-based authentication/authorization or use a traditional login in flow.

How can I use constant ConnectionId in Signalr?

I am working in Asp.Net Core Mvc Signalr. My system works like below image but connectionid changes every refresh all in another browser. I want to use constant connection id for all users and store this connection id and user's id in database . How Can I use Constant connection Id.
Here is my js code
"use strict";
$(document).ready(() => {
var connection = new signalR.HubConnectionBuilder().withUrl("/chathub").build();
connection.on("connected", connecitonid => $("#connectionId").html(connecitonid));
connection.start();
$("button").click(() => {
let message = $("#txtMessage").val();
var user = $("#sender").val();
connection.invoke("ClientSendMessage", $("#client").val(),user, message)
.catch(error => console.log("Error." + error));
var div = document.createElement("div");
div.textContent = "me" + ":" + message;
document.getElementById("son").appendChild(div);
});
connection.on("ReceiveMessage", function (user, message) {
var msg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
var encodedMsg = user + ":" + msg;
var div = document.createElement("div");
div.textContent = encodedMsg;
document.getElementById("son").appendChild(div);
});
});
Here is my hub class
using MentorShip.Models;
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MentorShip.Hubs
{
public class SignalRChat:Hub
{
public async Task ClientSendMessage(string connectionId,string user, string message)
{
await Clients.Client(connectionId).SendAsync("ReceiveMessage",user, message);
}
public async override Task OnConnectedAsync()
{
await Clients.Caller.SendAsync("connected", Context.ConnectionId);
}
}
}
Here is my html code
<div class="container">
<div class="row"><h5>Connection ID : <span id="connectionId"></span></h5></div>
<div class="row">
<div class="col-md-7"><input type="text" id="sender" value="Sender Name"></div>
</div>
<div class="row">
<div class="col-md-7"><input type="text" placeholder="ReceiverId" id="client"></div>
</div>
<div class="row">
<div class="col-md-7"> <input type="text" id="txtMessage"> <button>Send</button></div>
</div>
<div class="row">
<div class="col-md-7" id="son"> </div>
</div>
</div>
Here is how code works
This connection id every time changes

Simple Role Manager and authorization In ASP.NET MVC 5 without using Identity(CustomRoleProvider)

Custom Role Provider and authorization without using Identity in ASP.NET MVC 5
Here is the Roles Controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace SN.Helios.Portal.Controllers
{
[Authorize(Roles = "Admin")]
public class RolesController : Controller
{
// GET: Roles
public ActionResult Index()
{
var context = new ApplicationDbContext();
var rolelist = context.Roles.OrderBy(r => r.RoleName).ToList().Select(rr =>
new SelectListItem { Value = rr.RoleName.ToString(), Text = rr.RoleName }).ToList();
ViewBag.Roles = rolelist;
var userlist = context.Employees.OrderBy(u => u.FullName).ToList().Select(uu =>
new SelectListItem { Value = uu.FullName.ToString(), Text = uu.FullName }).ToList();
ViewBag.Users = userlist;
ViewBag.Message = "";
return View();
}
// GET: /Roles/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Roles/Create
[HttpPost]
public ActionResult Create(Role role)
{
try
{
var context = new ApplicationDbContext();
context.Roles.Add(role);
context.SaveChanges();
ViewBag.Message = "Role created successfully !";
return RedirectToAction("Index");
}
catch
{
return View();
}
}
public ActionResult Delete(string RoleName)
{
var context = new ApplicationDbContext();
var thisRole = context.Roles.Where(r => r.RoleName.Equals(RoleName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
context.Roles.Remove(thisRole);
context.SaveChanges();
return RedirectToAction("Index");
}
//
// GET: /Roles/Edit/5
public ActionResult Edit(string roleName)
{
var context = new ApplicationDbContext();
var thisRole = context.Roles.Where(r => r.RoleName.Equals(roleName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
return View(thisRole);
}
//
// POST: /Roles/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Role role)
{
try
{
var context = new ApplicationDbContext();
context.Entry(role).State = System.Data.Entity.EntityState.Modified;
context.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
// Adding Roles to a user
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult RoleAddToUser(string UserName, string RoleName)
{
var context = new ApplicationDbContext();
if (context == null)
{
throw new ArgumentNullException("context", "Context must not be null.");
}
Employee user = context.Employees.Where(u => u.FullName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
Role role = context.Roles.Where(u => u.RoleName.Equals(RoleName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
AssignUserRole assignUserRole = new AssignUserRole
{
EmployeeId = user.EmployeeID,
RoleId = role.RoleID
};
var EmpRoleToAdd = (from emprole in context.AssignUserRoles
where emprole.EmployeeId == user.EmployeeID && emprole.RoleId == role.RoleID
select emprole).FirstOrDefault();
if (EmpRoleToAdd == null)
{
context.AssignUserRoles.Add(assignUserRole);
context.SaveChanges();
ViewBag.Message = "Role created successfully !";
}
else
{
ViewBag.Message = " This Role already exists for this user !";
}
// Repopulate Dropdown Lists
var rolelist = context.Roles.OrderBy(r => r.RoleName).ToList().Select(rr => new SelectListItem { Value = rr.RoleName.ToString(), Text = rr.RoleName }).ToList();
ViewBag.Roles = rolelist;
var userlist = context.Employees.OrderBy(u => u.FullName).ToList().Select(uu =>
new SelectListItem { Value = uu.FullName.ToString(), Text = uu.FullName }).ToList();
ViewBag.Users = userlist;
return View("Index");
}
//Getting a List of Roles for a User
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult GetRoles(string UserName)
{
if (!string.IsNullOrWhiteSpace(UserName))
{
var context = new ApplicationDbContext();
Employee user = context.Employees.Where(u => u.FullName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
var roles = user.AssignUserRoles.Select(u => u.Role).Select(u => u.RoleName).ToArray();
ViewBag.RolesForThisUser = roles;
// Repopulate Dropdown Lists
var rolelist = context.Roles.OrderBy(r => r.RoleName).ToList().Select(rr => new SelectListItem { Value = rr.RoleName.ToString(), Text = rr.RoleName }).ToList();
ViewBag.Roles = rolelist;
var userlist = context.Employees.OrderBy(u => u.FullName).ToList().Select(uu =>
new SelectListItem { Value = uu.FullName.ToString(), Text = uu.FullName }).ToList();
ViewBag.Users = userlist;
ViewBag.Message = "Roles retrieved successfully !";
}
return View("Index");
}
//Deleting a User from A Role
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult DeleteRoleForUser(string UserName, string RoleName)
{
var context = new ApplicationDbContext();
Employee user = context.Employees.Where(u => u.FullName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
Role role = context.Roles.Where(u => u.RoleName.Equals(RoleName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
var EmpRoleToDelete = (from emprole in context.AssignUserRoles
where emprole.EmployeeId == user.EmployeeID && emprole.RoleId == role.RoleID
select emprole).FirstOrDefault();
if (EmpRoleToDelete != null)
{
context.AssignUserRoles.Remove(EmpRoleToDelete);
context.SaveChanges();
ViewBag.Message = "Role removed from this user successfully !";
}
else
{
ViewBag.Message = "This user doesn't belong to selected role.";
}
// Repopulate Dropdown Lists
var rolelist = context.Roles.OrderBy(r => r.RoleName).ToList().Select(rr => new SelectListItem { Value = rr.RoleName.ToString(), Text = rr.RoleName }).ToList();
ViewBag.Roles = rolelist;
var userlist = context.Employees.OrderBy(u => u.FullName).ToList().Select(uu =>
new SelectListItem { Value = uu.FullName.ToString(), Text = uu.FullName }).ToList();
ViewBag.Users = userlist;
return View("Index");
}
}
}
Create Index View for Roles Controller
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_mainView.cshtml";
}
<div class="row col-sm-12 col-lg-12 col-md-12">
<h1 style="text-align:center">Role Manager</h1>
<br />
</div>
<div class="row col-sm-12 col-lg-12 col-md-12">
<div class="col-sm-6 col-lg-6 col-md-6">
<div class="panel panel-primary">
<div class="panel-heading">
<h4>Role List</h4>
</div>
<div class="panel-body">
<table class="table table-striped table-hover col-sm-6 col-lg-6 col-md-6 ">
#foreach (var role in ViewBag.Roles)
{
<tr>
<td class="col-sm-1 col-lg-5 col-md-5">
<strong>#role.Text </strong>
</td>
<td class="col-sm-1 col-lg-1 col-md-1">
<span onclick="return confirm('Are you sure to delete?')">Delete</span> |
#Html.ActionLink("Edit", "Edit", new { roleName = #role.Text })
</td>
</tr>
}
</table>
</div> <!-- End Panel Body-->
</div> <!-- End Panel -->
<div class="panel panel-primary">
<div class="panel-heading">
<h4>Create A New Role</h4>
</div>
<div class="panel-body">
#using (Html.BeginForm("Create", "Roles", new { #class = "form-horizontal" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div>
Role name: #Html.TextBox("RoleName")
<input type="submit" value="Save" class="btn-primary" />
</div>
}
</div> <!--End Panel Body-->
</div> <!--End Panel-->
</div> <!--End First Column-->
<div class="col-sm-6 col-lg-6 col-md-6">
<div class="panel panel-primary">
<div class="panel-heading">
<h4>Add a Role to a User</h4>
</div>
<div class="panel-body">
#using (Html.BeginForm("RoleAddToUser", "Roles"))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<p>User Name: #Html.DropDownList("UserName", (IEnumerable<SelectListItem>)ViewBag.Users, "Select ...")</p>
<p>Role Name: #Html.DropDownList("RoleName", (IEnumerable<SelectListItem>)ViewBag.Roles, "Select ...")</p>
<p><input type="submit" value="Save" class="btn-primary" /></p>
}
</div> <!-- End Panel Body-->
</div> <!-- End Panel -->
<div class="panel panel-primary">
<div class="panel-heading">
<h4>List Roles for a User</h4>
</div>
<div class="panel-body">
#using (Html.BeginForm("GetRoles", "Roles"))
{
#Html.AntiForgeryToken()
<p>
User Name: #Html.DropDownList("UserName", (IEnumerable<SelectListItem>)ViewBag.Users, "Select ...")
<input type="submit" value="Get Roles for this User" class="btn-primary" />
</p>
}
#if (ViewBag.RolesForThisUser != null)
{
<div class="alert-info">
<strong>Roles for this user </strong>
<ol>
#foreach (string s in ViewBag.RolesForThisUser)
{
<li>#s</li>
}
</ol>
</div>
}
</div> <!-- End Panel Body-->
</div> <!-- End Panel -->
<div class="panel panel-primary">
<div class="panel-heading">
<h4>Remove Role from User</h4>
</div>
<div class="panel-body">
#using (Html.BeginForm("DeleteRoleForUser", "Roles"))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<p>User Name: #Html.DropDownList("UserName", (IEnumerable<SelectListItem>)ViewBag.Users, "Select ...")</p>
<p>Role Name: #Html.DropDownList("RoleName", (IEnumerable<SelectListItem>)ViewBag.Roles, "Select ...")</p>
<p><input type="submit" value="Delete this user from Role" class="btn-primary" /></p>
}
</div> <!-- End Panel Body-->
</div> <!-- End Panel -->
</div> <!--End Second Column-->
</div> <!--Overall Page Wrapper-->
<div class="alert-info col-sm-12 col-lg-12 col-md-12">
#ViewBag.Message
</div>
---------------------------------------------------------------------
Create Edit View For Roles Controller
#model yournamespace.Role
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_mainView.cshtml";
}
<h2>Edit Role</h2>
#Html.ActionLink("Return to Role Manager", "Index")
<hr />
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.RoleID)
<div>
Role name
</div>
<p>
#Html.TextBoxFor(model => model.RoleName)
</p>
<input type="submit" value="Save" />
}
Create Roles and Assign to the Users
Create Class CustomRoleProvider
Inherit CustomRoleProvider from RoleProvider class as shown below and implement abstract class.Make changes in the classes as shown below
using System;
using System.Linq;
using System.Web.Security;
namespace yournamespace.Models
{
public class CustomRoleProvider : RoleProvider
{
public override string ApplicationName { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override void CreateRole(string roleName)
{
throw new NotImplementedException();
}
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
{
throw new NotImplementedException();
}
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
{
throw new NotImplementedException();
}
public override string[] GetAllRoles()
{
using (var usersContext = new SNHeliosWork2017Entities())
{
return usersContext.Roles.Select(r => r.RoleName).ToArray();
}
}
public override string[] GetRolesForUser(string username)
{
using (var usersContext = new SNHeliosWork2017Entities())
{
var user = usersContext.Employees.SingleOrDefault(u => u.FullName == username);
if (user == null)
return new string[] { };
return user.AssignUserRoles == null ? new string[] { } :
user.AssignUserRoles.Select(u => u.Role).Select(u => u.RoleName).ToArray();
}
}
public override string[] GetUsersInRole(string roleName)
{
throw new NotImplementedException();
}
public override bool IsUserInRole(string username, string roleName)
{
using (var usersContext = new SNHeliosWork2017Entities())
{
var user = usersContext.Employees.SingleOrDefault(u => u.FullName == username);
if (user == null)
return false;
return user.AssignUserRoles != null && user.AssignUserRoles.Select(
u => u.Role).Any(r => r.RoleName == roleName);
}
}
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override bool RoleExists(string roleName)
{
throw new NotImplementedException();
}
}
}
In web.config add the following code within system.web tag
<system.web>
<sessionState mode="InProc" timeout="20" cookieless="false"></sessionState>
<authentication mode="Forms">
<forms loginUrl="~/Home/LogIn" defaultUrl="~/" timeout="20" slidingExpiration="true"/>
</authentication>
<roleManager enabled="true" defaultProvider="CustomRoleProvider">
<providers>
<clear/>
<add name="CustomRoleProvider" type="MyProject.Models.CustomRoleProvider" />
</providers>
</roleManager>
</system.web>
The first thing to note is that I have set the enabled attribute to true so that the framework enables the role manager. Then you have to specify the defaultProvider attribute, which is used to identify the default provider if a number of providers are specified. But in this case, I am going to have only one provider CustomRoleProvider, still the default provider has to be specified. This is contained within the providers element. The clear element is used to clear all the providers stored for this application earlier, for example the default providers. Then I have defined the custom role provider by specifying the name "CustomRoleProvider", which was used in the defaultProvider attribute. This contains a number of attributes. The most important one is the type attribute where the fully-qualified name of the custom role provider is specified (MyProject.Models.CustomRoleProvider), followed by the assembly containing this type (MyProject) and the version. Note that only the type name is required and others are optional if the type is contained within the same assembly - the web application itself. Other attributes are self-explanatory and I am not going to bore you with all these details!
Use authorize attribute to authorize controllers
As,
[Authorize(Roles = "Admin")]
public class RolesController : Controller
{
}

Recaptcha doesn't work with ajax and partial views

I'm using Recaptcha in my MVC4 web app. It was working correctly when it was embedded in the form but when I moved the #Html.Raw(Html.GenerateCaptchaHelper()) to partial view and trying to call this partial view via ajax request, it doesn't work!
Extension code :
public static string GenerateCaptchaHelper(this HtmlHelper helper)
{
var captchaControl = new Recaptcha.RecaptchaControl
{
ID = "recaptcha",
Theme = "clean",
PublicKey = ************,
PrivateKey = **********************,
Language = "En"
};
var htmlWriter = new HtmlTextWriter(new StringWriter());
captchaControl.RenderControl(htmlWriter);
return htmlWriter.InnerWriter.ToString();
}
my partial view is has the code like :
<p>#Html.Raw(Html.GenerateCaptchaHelper())</p>
and inside my controller
public PartialViewResult Captcha()
{
return PartialView();
}
and inside my main view:
#using (Html.BeginForm("Login", "Account", new { returnUrl = ViewData["ReturnUrl"] }, FormMethod.Post,null))
{
#Html.AntiForgeryToken()
<form role="form">
<div class="form-group">
<label>#Html.LabelFor(m => m.Email)</label><br />
#Html.TextBoxFor(m => m.Email, null, new { #class = "form-control", autocomplete = "off" })
</div>
<div class="form-group">
<label>#Html.LabelFor(m => m.Password)</label><br />
#Html.PasswordFor(m => m.Password, new { #class = "form-control", autocomplete = "off" })
</div>
<div id="captchaView" class="form-group">
</div>
<button type="submit">Login</button>
</div>
</div>
</form>
}
and the javascript is :
$.ajax({
url: '/Account/Captcha',
type: 'GET',
success: function(data) {
$('#captchaView').html(data);
}
});
Could you please help me to figure out why?