ASP.NET MVC Multiple Authentication - asp.net-mvc-4

I have two types of user in my database one is user and another is admin. I have made user and admin login and both of them works. I have use [Authorize] in some user classes and whenever I browse that link it will automatically redirect towards user login. Now, here comes the problem. I have used [Authorize] in some admin class also, hoping to redirect toward admin login but it will redirect towards user login.
Web.Config
<authentication mode="Forms">
<forms loginUrl="~/Login/LoginView" timeout="2880"/>
</authentication>
AdminRetrieveCrimeReportController.cs
using OnlineCrimeReportingSystem.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace OnlineCrimeReportingSystem.Controllers
{
[Authorize]
public class AdminRetrieveCrimeReportController : Controller
{
private OnlineCrimeReportingSystemEntities2 context = new OnlineCrimeReportingSystemEntities2();
// GET: AdminRetrieveCrimeReport
public ActionResult AdminRetrieveCrimeReportView()
{
var model = context.Crimes.ToList();
return View(model);
}
public ActionResult DeactiveCrime(int id)
{
var crime = context.Crimes.Find(id);
crime.Status = false;
context.Entry(crime).State = System.Data.Entity.EntityState.Modified;
context.SaveChanges();
return RedirectToAction("AdminRetrieveCrimeReportView");
}
}
}
This page AdminRetrieveCrimeReportView should redirect toward AdminLogin but it will redirect toward Userlogin please help me.

Related

Do I must have "Google Workspace" account to enable "Google Keep API"?

I keep running into "invalid scope" error while enabling "Google Keep API"
I've tried other APIs like "Google drive API" with same code and it worked,but fail for google keep.
I search on Internet,it seems that I need to have "Google Workspace"account to enable it,is that true?
I use .netcore3.1 mvc to implement the Oauth2.0 authentication but it failed for Google Keep....
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using test_coremvc.Models;
using Google.Apis.Auth.AspNetCore3;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v3;
using Google.Apis.Services;
using Google.Apis.Keep.v1;
namespace test_coremvc.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
[GoogleScopedAuthorize(KeepService.ScopeConstants.Keep)]
public async Task<IActionResult> KeepFileList([FromServices] IGoogleAuthProvider auth)
{
GoogleCredential cred = await auth.GetCredentialAsync();
var service = new KeepService(new BaseClientService.Initializer
{
HttpClientInitializer = cred
});
//var files = await service.Files.List().ExecuteAsync();
//var fileNames = files.Files.Select(x => x.Name).ToList();
return View();
}
}
}
Google Keep API is an enterprise-only API used to create and manage the Keep notes within your domain, including resolving issues identified by CASB software.
In addition, the official documentation shows that you need to create a service account and authorize it. A service account is a special kind of account used by an application, rather than a person. You can use a service account to access data or perform actions by the robot account, or to access data on behalf of Google Workspace or Cloud Identity users.
So, it may only work with Google Workspace domain accounts.
We recommend you use the service account method, but if you don't want to create a service account, you can refer to Gabriel Carballo's answer to use the admin-approved method (tip: I have not verified this method, just as a suggestion).

'HttpRequest' does not contain a definition for 'CreateResponse' and no accessible extension method

The below is my code. It looks HttpRequest could not able to access CreateResponse. Kindly help.
using System;
using System.Net;
using System.Net.Http;
using Microsoft.AspNetCore.Mvc;
namespace Abc.Controllers
{
[ApiController]
[Route("[controller]")]
public class PaymentController : Controller
{
public HttpResponseMessage Post()
{
// ... do the job
// now redirect
var response = Request.CreateResponse(HttpStatusCode.Moved);
response.Headers.Location = new Uri("http://www.abcmvc.com");
return response;
}
}
}
HttpResponseMessage and Request.CreateResponse are legacy ways to produce a HTTP response from older ASP.NET days, which do not apply to ASP.NET Core. If you have an ASP.NET Core application, you should use the mechanisms of ASP.NET Core, in particular the action results, to produce responses.
In your case, if you want to produce a redirect to some other location, then you can do it like this in ASP.NET Core:
public IActionResult Post()
{
// ... do the job
return RedirectPermanent("http://www.abcmvc.com");
}
This uses the RedirectPermanent utility method to create a RedirectResult.

IdentityServer4 How can I redirect after login to the revious url page without registering all routes at IdP

As recommend I would have register the authorize callback url/redirect_url at IdP, which it works.
But what if a client using MVC app tries to access a page with an unauthorized state, will be redirect to idsrv login page.
The redirect_url is always (Home page entry point) as configured.
To change this behavior I would have to register all possible routes at IdP.
That can not a be solution!
On idsrv Login method I have tried:
Login(string returnUrl)
checking the value from returnUrl it gives /connect/authorize/callback?client_id=...
Shouldn't returnUrl have the url of the previous page? Like in a normal mvc app has..
I have tried to get Referer store it on session and then redirect..
if (!string.IsNullOrEmpty(Request.Headers["Referer"].ToString()))
{
this.httpContextAccessor.HttpContext.Session.SetString("Referer", Request.Headers["Referer"].ToString());
}
But that doesn't work Referer comes null...
I have checked what's coming on context from interation services
var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);
context.RedirectUri
And returns /signin-oidc/ this is the automated way for returning (Home page entry point).
Any chance to get the previous url, so that the user can be redirect?
So what can I do else?
I'm using Hybrid flow to manage the following clients : mvc-app, classic-asp, web api
Here's an example of implementation allowing you to achieve what you want. Keep in mind that there's other ways of doing it.
All the code goes on your client, the server never knows anything about the end url.
First, you want to create a custom attribute that will be decorating all your actions/controllers that you want to protect:
using System;
using System.Web.Mvc;
namespace MyApp
{
internal class MyCustomAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (filterContext.Result is HttpUnauthorizedResult)
{
filterContext.RequestContext.HttpContext.Session["oidc-returnUrl"] = filterContext.RequestContext.HttpContext.Request.UrlReferrer?.PathAndQuery;
}
}
}
}
And then you are going to create a login route/action that will handle all your authorize requests:
using System.Web.Mvc;
namespace MyApp
{
public class AccountController : Controller
{
[MyCustomAuthorize]
public ActionResult Login()
{
returnUrl = Session["oidc-returnUrl"]?.ToString();
// clean up
Session["oidc-returnUrl"] = null;
return Redirect(returnUrl ?? "/");
}
}
}
The login path can be changed in your startup code:
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
LoginPath = "/my-login"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
// setting up your client
});
}
}

How to redirect to admin login page in mvc internet application template? (by defaut, it redirect to account/login page))

I have login page in user site and adminlogin page in admin site
I have action
[Authorize]
public ActionResult ChangeProfile(User model)
{
// my code
}
and action in admin site
[Authorize(Roles="Admins")]
public ActionResult UserManager(User model)
{
// my code
}
I like when i access to action ChangeProfile => redirect to login page in user site (if not login)
and when i access to action UserManager => redirect to adminlogin page in admin site (if not login with Admins roles)
Please help me to show me what could i do, thank you so much!
Use custom AuthorizeAttribute and override HandleUnauthorizedRequest.
public class CustomAuthorize: AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAuthenticated)
base.HandleUnauthorizedRequest(filterContext);
else
filterContext.Result = new RedirectToRouteResult(new
RouteValueDictionary("Admin login route"));
}
}
[CustomAuthorize(Roles="Admins")]
public ActionResult UserManager(User model)
{
// my code
}
If you have something like this in your web.config file:
<forms loginUrl="~/Account/LogOn" timeout="2880" />
change it to this but i'm not really sure it works or not but you can try:
<forms loginUrl="/Account/LogOn" timeout="2880" />

Creating a custom role principal to be used with custom role provider, How do I get IIdentity to pass as parameter?

I have a custom Role provider for my MVC4 application that is working so well in that it creates roles, checks role existence, check IsUserInRole but my [Authorize(Roles = "Admin")] is still using the default System.Web.Security.RolePrincipal.IsInRole(String role) method
I have tried to create a custom RolePrincipal that overrides the IsInRole method but I am having problem finding the correct parameter for the constructor and am unsure how to set this in the web.config. Code is as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration.Provider;
using MetaLearning.Data;
using System.Web.Security;
namespace Project.Principal
{
public class MyPrincipal : System.Web.Security.RolePrincipal
{
private MyContext dbcontext = new MyContext(System.Configuration.ConfigurationManager.ConnectionStrings["MyContext"].ConnectionString);
private Repository<MyUser> userRepository;
private Repository<Role> roleRepository;
public MyPrincipal()
{
this.userRepository = new Repository<MyUser>(dbcontext);
this.roleRepository = new Repository<Role>(dbcontext);
}
public override bool IsInRole(string role)
{
Role roleCheck = roleRepository.Get(r => r.Name == role).FirstOrDefault();
MyUser user = userRepository.Get(u => u.Username == HttpContext.Current.User.Identity.Name).FirstOrDefault();
user.RoleID = roleCheck.RoleID;
userRepository.Update(user);
userRepository.SaveChanges();
return true;
}
}
}
I checked the RolePrincipal documentation http://msdn.microsoft.com/en-us/library/system.web.security.roleprincipal.aspx and can see that the most basic constructor RolePrincipal(IIdentity) takes a parameter of IIdentity. How and where can this be retrieved from as I am unsure as to what it is? Are there additional changes required in the webconfig?