I'm implementing a custom ASP.NET role provider, and I'm wondering whether its AddUsersToRoles method should throw a ProviderException if a user passed in is already in a role passed in. The default Microsoft SQL Server role provider SqlRoleProvider exhibits this behaviour, even though the official Microsoft documentation doesn't recommend it:
Exception Details: System.Configuration.Provider.ProviderException: The user 'myTestUser' is already in role 'myTestRole'.
I think it would be useful for my provider not to throw an exception in this case but just to move on when a given user is already in a given role; that way the calling code doesn't need to worry about duplicates. But could there be existing role provider-using code that relies on an exception being thrown in this case? If there is, should it be doing so given that Microsoft themselves don't seem to recommend it?
If I do want to implement a method similar to AddUsersToRoles that doesn't throw an exception when a user is already in a role, I can see 3 alternatives:
Implement it as AddUsersToRoles and just have different behaviour from the default SqlRoleProvider.
Implement it as a new EnsureUsersInRoles method in my role provider class, and access it from my calling code using ((MyProvider)(Roles.Provider)).EnsureUsersInRoles().
Just implement it in a totally separate class.
Personally, I'd conform to what Microsoft does. It would be hard to rule out the possibility that something somewhere does require that exception to be thrown.
I ended up going down route 2) that I proposed in my question; I implement a RoleProvider with some additional methods as well, and then use the cast ((MyProvider)(Roles.Provider)) to get access to my additional methods, one of which is EnsureUsersInRoles(), which has the non-Exception-throwing functionality that my calling code wants.
Related
Okay, I'm open to being told I'm approaching the problem incorrectly, so go ahead if that's the case, but I have a unhandled exception provider I'm adding to my builder.Services in program.cs, along with some data services. I can't figure out a good way to add an existing data service to the unhandled exception provider (custom logging to a db via the data service).
I had tried passing it, or using it via injection, but in the exception provider the data service keeps coming up as null in practice.
So I was thinking, is there a way to get a reference to the WebApplication that is running (the one we are running via app.Run() in Program.cs) from elsewhere in the running program.
Logically, I'd like to do something like this in the unhandled exception provider:
MyService = GetRunningApp().services.BuildServiceProvider().GetService<IMyService>();
Am I missing an easier way to do this?
In Blazor it's not as easy to inject the middleware for global error handling like it is with Web API (Correct me if I'm wrong!)
For Blazor I think the closest we have is the <ErrorBoundary>. Check out this solution by Alamakanambra. They provide an example on how to create a component that handles global exceptions. You can do whatever logging or handling you need in the OnErrorAsync.
protected override Task OnErrorAsync(Exception exception)
{
receivedExceptions.Add(exception);
return base.OnErrorAsync(exception);
}
Spring Security can be a nightmare for the new user. Nothing is solid, everything can be configured by some #Autowired bean or other, there are a million options, and seemingly simple things become very complex very quickly.
<End of Rant>
Now then, I have the following requirements and setup for a corporate intranet application:
1) I am trying to avoid the use of security.xml and configure everything with java annotations.
2) There is a central corporate cookie-based authentication service which authenticates the user as someone entitled to use the corporate intranet. Usernames and Passwords are handled there, the application does not concern itself with them. There is a wealth of other information there, most of which my application doesn't need. The one absolute essential there is the userid entered by the user and validated by the service. This goes into the Principal and also is available as session data. This service is supplied as a servlet filter.
3) This filter includes a configuration option through which an adaptor can be attached, to perform other tasks, such as getting the authenticated user's application-specific roles from an application-maintained database. I am using such an adaptor for this task, which adds the roles from the database to an object that winds up in the Session attributes in some structure. By the end of this filter's and adaptor's execution the user's application-specific roles are in the session data.
4) I have added a class derived from com.att.voicetone.cwing.security.AbstractSecurityWebApplicationInitializer and in its beforeSpringSecurityFilterChain() method, have registered this filter from step 2 (which includes the adaptor from step 3) so that it is done first. All the above is working as I want it to work.
5) Now, I am looking at how all this may be tied into Spring Security. My goal is to be able to use something like this:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/index.html","/transcripts.html").hasRole("MY_APP_USER");
http.authorizeRequests()
.antMatchers("/assign.html","/report.html").hasRole("MY_APP_ADMIN");
http.authorizeRequests()
.antMatchers("/", "/x/**", "/audio/**").hasRole("MY_APP_USER");
http.authorizeRequests()
.antMatchers("/oam/**").hasRole("MY_APP_ADMIN");
}
It seems as though what I must do is implement a class that extends org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter, and insert it into the filter chain and somehow code it to translate the role information into a format that the hasRole() calls above will find the information they are looking for.
But this is the point, after all the "hard" work has seemingly been done, where I run into countless ConfigurationBuilders, AuthenticationManagers, AuthenticationTokens, etc., all of which have many customization opportunities, none of which seem to fit with the "simple" task I feel is waiting for me, somewhere, in the morass of configurable options, that I haven't been able to find through hours of starting at code, javadocs, etc.
If you've followed me thus far, what is the sweet spot I am missing for translating the roles from the above session object so that SpringSecurity can handle them with the hasRole() code?
Or to put it another way, where is hasRole() looking and what does it expect to find there?
The answer to this question is that you do the "translation" in a AuthenticationDetailsSource, which creates the UserDetails object which has the collection of GrantedAuthorities. That is the piece that I was missing.
However, I'm still not out of the woods. On to my next SO question ...
I need to slightly tweak the functionality of the ASP.NET Membership provider to add custom logging functionality. Instead of creating a wrapper class around the methods I wish to modify, I was toying with the idea or creating a custom Membership Provider and override a few of the methods.
All the examples I could find would show how to create it from scratch. I don't want to overwrite everything... just override a few methods. Can somebody point me in the right direction?
Thanks!
EDIT:
DOH! I can simply inherit from SqlMembershipProvider and override the methods. However, how can I get at the connection string?
What is it that you are trying to log?
If you simply want to monitor success and failure of authentication, ASP.NET Health Monitoring is already in the box. Events are logged to the WebEvent tables.
If you have other motives, well then..... ;-)
to answer your question about the connection string, override Initialize and capture the value from the config argument before calling base.Initialize
I am using The Policy Injection Application Block to log methods that are called in my ASP.NET application. I would like these log entries to include information like the current user identity, whether the user is authenticated and so forth. All of this information is provided by the ManagedSecurityContextInformationProvider, but I can't figure out how to get the PIAB to use that provider and how to get that information into my log file.
I may be missing something obvious, but I can't quite figure out what it is.
Sorry to say, it looks like there is no way to get the ManagedSecurityContextInformationProvider information into method call logs. That information is usually logged in extended properties but the LogCallHandler.GetLogEntry method dumps out all of the method parameters and assigns them to the TraceLogEntry ExtendedProperties.
It seems to me that you could either modify the block to add that information or (even better) create your own Custom Call Handler based on LogCallHandler that adds the information that you require. Either option is not that much work.
I'm using JQuery to load controls dynamically in an ASP.NET development environment using JSON and WebServices. Within this solution I have a business logic layer which has a built in validation mechanism (i.e. validating properties and business rules similar to that of CSLA)
When requesting a new control to be loaded dynamically using JQuery and an ASP.NET WebService, I would like to validate the input from the current control against the business logic validation mechanism (i.e. server side validation) and notify the user if there was any problems.
I managed to achieve this, however, when validation fails in the web service I would like to throw a customer exception containing the validation field id's and associated error messages.
In JQuery, I test for this specific ExceptionType and would like to apply the error messages dynamically to the controls listed in the exception type properties. This is where my problem comes in. Even though I created a custom exception with custom properties the exception that is passed to JQuery in JSON format from the WebService is still a standard exception with none of the additional properties listed. I could simply create a JSON formatted string of values in the exception's message property but would ultimately prefer something a little more elegant. Does anyone know how you can override the serialized exception created by ASP.NET for situations such as this...
Thank you in advance...
G
I ran into something very similar a couple days ago - basically there's no way to make ASP.NET generate custom exceptions. This is by design, since returning a specific type of exceptions would
[...] expose implementation
details/bugs to the clients. We could
do something with special exception
type that we let pass through, but its
too late for this release [...]
You could always return different HTTP status codes, and have the browser handle them as custom exceptions - for example, a 500 error would mean one thing, a 401 something else, etc. I think the best solution is to make your method return a string with the exception stack - not elegant, but at least this way the client has all the exception details.
Dave Ward also has info on ASP.NET AJAX service errors.