I have an ASP.NET MVC 3 project where I have NO local user management. I have intergratred Facebook Connect successfully. While this works, it makes my Controllers and Views messy and verbose.
I'd like to replace the default objects such as the User object exposed by Controllers and Views to return my FacebookUser object instead.
Anyone have a better solution than having my Controllers digging around in FacebookWebContex.? It just feels dirty.
Not quite sure which facebook library you are using. But if you impliment IPrincipal and IIdentity in your FacebookUser object, you will be able to set HttpContext.Current.User to that FacebookUser which will allow you to pull that FacebookUser instance from the User property in the controller.
Related
I am messing around making an app in grails. At this point I have already made a login view and the controller. How its working is I got a service which queries my db for the credentials and then if they are valid proceeds to the main screen as shown below. Now I need to add a session to it so that you cant bypass the login. Keep in mind I got no Domain classes because all I need Im querying the database.
This is how the controller works rn:
The login service is basically a firstrow query.
It isn't clear what you really need but in your controller is a variable named session which you can interact with as a Map and do things like session.isLoggedIn = true or if(session.isLoggedIn) { ... } etc. You probably shouldn't do that sort of thing in your app though. You should consider something like https://grails-plugins.github.io/grails-spring-security-core/.
Let's say I have 3 entities: Advert, User and UserRole. And in Web.Api project GetAllAdverts method.
public IEnumerable<Advert> GetAllAdverts()
{
return repository.GetAll<Advert>();
}
When i enter url ../api/advert I get JSON with all Adverts and data about adverts, but I get all data about user and user role too.
How can I get for example all advert data and only UserName form entity User ?
Is this done by creating DTOs ?
Thanks in advance !
Using DTO's is usually a good idea. It is more work, but it gives you full control and it abstracts out peculiarities of a specific data layer.
In your case, if you really only want UserName you even have to use a DTO, because it is impossible to partly load the User as navigation property from Advert.
If it does not matter that you see all properties of User except its navigation properties (like role), you may also consider to (temporarily) turn off lazy loading for the context in the repository and eager load Advert.User by using Include.
After developing for iOS for some time now, I have gotten comfortable with the language and am trying to get better at designing well-structured applications. Initially my focus was on seeing something functional, so I ended up with gigantic view controllers which were horribly architected. Now, I'm learning to separate my model classes and trying to keep my architecture more modular. I would greatly appreciate any advice on the following sample situation:
I am developing an app which (among other things) pulls a list of articles from a server and displays them. However, the user has to be authenticated to be able to retrieve this list. Because other aspects of the application utilize the same authentication, I want a single class to manage the authentication. The goal is that when any controller requests data from the model which requires authentication, if the user is not authenticated, the authentication prompt will automatically be presented.
I expect to create the following:
VIEW
- ArticlesView
- AuthenticationView
CONTROLLER
- ArticlesViewController
- AuthenticationViewController
- ArticleManager (singleton)
- AuthenticationProvider (singleton)
MODEL
- Article
When the application first loads, execution will reach the ArticlesViewController's viewDidLoad method. In this method, I get a shared instance of the ArticleManager, specify the authentication class to be the authentication provider, and ask it for a list of recent articles.
// ArticlesViewController.m
-(void) viewDidLoad {
...
AuthenticationProvider *authProvider = [AuthenticationProvider sharedInstance];
[[ArticleManager sharedInstance] setAuthenticationProvider:authProvider];
[[ArticleManager sharedInstance] fetchNewArticles];
}
If no authentication was necessary, the ArticleManager would successfully retrieve the list from the server and post a notification letting anyone interested know that the articles have been retrieved. The ArticlesViewController would handle this notification:
// ArticlesViewController.m
- (void) handleNewArticlesNotification:(NSNotification *)note {
[self updateUI];
}
However, if authentication is required, the user needs to be presented with a login screen before the articles can be fetched and displayed. So I imagine the ArticleManager doing something like this:
// ArticleManager.m
- (void) fetchNewArticles {
if( [self.authenticationProvider isAuthenticated] ){
// go fetch list from the web
}
else {
[self.authenticationProvider presentAuthenticationRequest];
}
}
Now, at this point I run into some difficulty fleshing out the remainder of the details. The AuthenticationProvider could present the AuthenticationViewController as a modal view controller from the AppDelegate's window's rootViewController and AuthenticationProvider would be the delegate of AuthenticationViewController. The AuthenticationViewController would probably be dumb to the actual actions that it is taking, and would have it's delegate (AuthenticationProvider) do the work to authenticate the user. Once the user is authenticated, AuthenticationProvider would dismiss the modal view controller (AuthenticationViewController).
But how does ArticleManager get notified that the authentication that it requested has completed? It would need to be able to handle both successful and failed authentication attempts separately. A successful authentication would eventually result in fetchNewArticles being called again.
One thought is for ArticleManager to be a delegate of AuthenticationProvider. This seems to work in this case, but there are other Model Managers which could also rely on AuthenticationProvider. Presumably this would be resolved if AuthenticationProvider is not a singleton. Would that be a decent design approach?
Thanks for taking the time to help me understand a good design approach. I have coded this a couple of times, but always get stuck/confused toward the end. Also, if the entire approach needs to be re-architected, please feel free to point me in another direction.
Many thanks!
I have always used Global NSNotifications to post when a user has logged in or logged out. Every view controller that presents data differently can subscribe to those notifications and update themselves accordingly when an event happens.
This is nice, because you may already have other views (perhaps in other tabs) that have already loaded and will need to refresh when a user has logged in or out.
One thought is for ArticleManager to be a delegate of
AuthenticationProvider. This seems to work in this case, but there are
other Model Managers which could also rely on AuthenticationProvider.
Presumably this would be resolved if AuthenticationProvider is not a
singleton. Would that be a decent design approach?
Perhaps instead you could have the AuthenticationProvider singleton provide AuthenticationSession objects, set the caller as the delegate of the AuthenticationSession, and ask the AuthenticationSession to perform the authentication.
Background: Completely new to MVC2. Has C# experience, but limited web experience.
I need more fine grained access than simply assigning a Role to a user. The user may have the role at 0+ points in a tree.
/
/Europe
/England
/France
/USA
For example, a user might be moderator of all forums under "Europe" and have access to posting news in France.
The two example controllers have actions as these:
ForumController:
public ActionResult DeletePost(int id) { ... }
NewsController:
[HttpPost]
public ActionResult Post(int treeID, ...) { ... }
How should I approach this? From what I gather Membership+RoleProvider cannot do this level of fine-grained control.
Previously I have written custom user/role/auth system which supported all this, but it was incompatible with "the standard" controls such as LoginView.
The goal would be to have roles allowing access like so:
NewsAdmin
Add news
Edit news
Delete news
NewsPoster
Add news
Therefore, the Post action of News controler should check: Does user have "Add news"-access where he is trying to post?
I would really like to somehow specify this using attributes, so the actual action code could be cleaner and just assume that the caller has appropirate access.
Hope the question makes sense, and I can get some pointers on where to read.
(Oh, and I'm sure this question has been answered in some variant before. I just can't seem to find it. I won't mind single-link replies, if you feel they might be helpful to read)
I think you're being too quick to dismiss the role provider. If a user had a role called NewsAdmin_Europe_AddNews that would pretty much answer the question, wouldn't it?
Once you've made your authentication scheme work with the role provider, you need to tie that into MVC. Subtype AuthorizeAttribute and override AuthorizeCore. Warning: Your code here must be thread-safe and re-entrant. Call base.AuthorizeCore and then test for the specific role based on the URI/query (you won't get route values since this can be served from cache, bypassing MVC altogether).
This is some work, but will be more secure in the end than trying to reinvent membership.
Problem:
I have a webforms app where every page inherits from BasePage.cs
I also have another class AuthenticatedBasePage.cs which inherits from BasePage.cs
BasePage.cs has some code which finds out if a Forms Authentication cookie is set, and if so, sets a IsAuthenticated boolean flag and a MyAppUser object (only has properties such as name, age, gendery) which means every page on the site can see if the user viewing the page is logged in or not, and if so, read the values of MyAppUser.
AuthenticatedBasePage has an additional feature where if anyone tries to browse to a page inheriting from this class are not authenticated, they are redirected to the login page with a 'returnurl' querystring variable set.
I would to have a similar setup in my MVC2 app. I've done a fair bit of reading that says I shouldn't reference HttpContext in my BaseController.cs (which all my controllers inherit from) as that means I can't unit test it. My first question is, how can I make the IsAuthenticated and MyAppUser objects available to every page? Secondly, how do I create pages which only authenticated users can access, and if they are not authenticated, they get redirected to the login page with the returnurl querystring variable set?
Many thanks,
A.
P.S. I'm not using the MembershipSchema, I'm only using the FormsAuthentication.SetCookie method.
What you want is the Authorize attribute. This article has a great explanation of how to use it with forms authentication.