Multiple buckets authentication with Admin user - spring-data-couchbase

I have multiple buckets and on my existing config I have a user for each bucket where the username is the name of the bucket and the password is a single password for all the buckets.. this is functioning as a work-around for rbac that was released with 5.x and the removal of bucket-level passwords.
Now I've spent many hours today figuring out how I can control all the buckets with a single admin user (in order for me to finally get rid of the many un-neccessary users)
I'm running latest couchbase 5.5.2 and spring-data-couchbase 3.1.1.RELEASE which should have the rbac support as mentioned here
The documentation doesn't mention how I can achieve this and the comments in the github link above are vague and I can't figure it out.

Finally figured it out.
You'll need to overwrite following method from AbstractCouchbaseConfiguration, specifying the rbac user
#Override
protected String getUsername() {
return "Admin";
}
Then change all your bucket beans to use openBucket(String s1) instead of openBucket(String s1, String s2)
#Bean
public Bucket kBucket() throws Exception {
return couchbaseCluster().openBucket("buck");
}

Related

Can I swap the current context Identity user with one pulled from userManager.Users.First

MVC Framework with Identity. Switching to OIDC. OIDC server provides email address instead of UserId. ApplicationSignInManager can't find the correct user. The user pulled from ApplicationSignInManager is much more robust with Firstname, Lastname, etc. We would have to change a lot of code if these weren't members of the user.
We'd like to catch this event and swap out the user in Startup.cs
private Task OnSecurityTokenValidated(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
var user = userManager.Users.First(u => u.Email == notification.AuthenticationTicket.Identity.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier").Value);
notification.OwinContext.Authentication.SignIn(user);
Except user we can't do that because
Cannot resolve method 'SignIn(EazeeApp.UI.Models.ApplicationUser)', candidates are:
void SignIn(Microsoft.Owin.Security.AuthenticationProperties, params System.Security.Claims.ClaimsIdentity[]) (in interface IAuthenticationManager)
This seems kinda gross, so I'm definitely up for some better, simpler solutions. I tried just dumping all the claims from the User into the notification.AuthenticationTicket.Identity but that won't include fields we need (but otherwise worked quite well).

Delete the expired or invalid openiddict tokens used in azure function

I am working on an azure function which is a part of a system. The authentication/ authorization of system is controlled by OpenIdDict library. After using our system for sometime in our production, there are millions of invalid and expired tokens in the OpenIddictTokens table which I believe is causing some of the calls in our system to slowdown.
Now I am working on a time triggered azure function whose purpose is to delete (get rid of) all the useless tokens & authorizations saved in the OpenIddictTokens and OpenIddictAuthorizations tables respectively.
I started looking at the openiddict documentation and api but could not find the exact match for my requirements related to implementation in azure yet.
Can someone please help? Thanks.
After looking into the documentation and experimenting with code, I was able to find the method and how to use this in my azure functions app.
First add the dependency for openiddict in startup:
builder.Services.AddOpenIddict()
// Register the OpenIddict core services.
.AddCore(options =>
{
// Register the Entity Framework stores and models.
options.UseEntityFrameworkCore()
.UseDbContext<ApplicationDbContext>();
});
Then create the respective function with the IOpenIddictAuthorizationManager and IOpenIddictTokenManager as dependencies and call the PruneAsync method for both.
private readonly IOpenIddictAuthorizationManager _openIddictAuthorizationManager;
private readonly IOpenIddictTokenManager _openIddictTokenManager;
public PruneTokenFunction(IOpenIddictAuthorizationManager openIddictAuthorizationManager, IOpenIddictTokenManager openIddictTokenManager)
{
_openIddictAuthorizationManager = openIddictAuthorizationManager;
_openIddictTokenManager = openIddictTokenManager;
}
[FunctionName("prunetoken")]
public async Task Run([TimerTrigger("0 */5 * * * ")] TimerInfo timerInfo)
{
await _openIddictTokenManager.PruneAsync(DateTimeOffset.Now.AddDays(-1));
await _openIddictAuthorizationManager.PruneAsync(DateTimeOffset.Now.AddDays(-1));
}
Also following is the issue related to same query which might be helpful to many. Implement automatic expired token flushing

Use Firebase.com authenication without forcing the user to create an account

I am developing a small App to allow the user to store To-Do items. I am using Firebase ass my backend.
For the first iteration I don't want the user to have to sign-up, but still only see it's own data. My first thought was just to use the anonymous authentication, store the UID an reuse it everytime the app is started. This is not possible since the session is gonna time out at some point and the user would get a new UID the next time.
I of course want to make sure that a user can only see it's own items using the Firebase Security & Rules.
The idea would be to save the items like this: app.firebase.com/user/123456/todo-item
123456 beeing the unique ID of the user.
Can I create a unique identifier myself and still use the Firebase Security & Rules?
You would have to run your own custom authentication solution.
When the Activity loads, you'll have to make a request to your server. Then on the server you can create tokens for a user when they load the page:
// These payload properties are accessible
// by Security Rules which is awesome
Map<String, Object> payload = new HashMap<String, Object>();
payload.put("uid", "uniqueId1");
payload.put("some", "arbitrary");
payload.put("data", "here");
TokenGenerator tokenGenerator = new TokenGenerator("<YOUR_FIREBASE_SECRET>");
String token = tokenGenerator.createToken(payload);
There's more packages than just Java, so read the docs.
Then when you deliver the token back to the user, you would need to store the token locally.
Once the token is stored, you can retrieve it and authenticate.
Firebase ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com/");
ref.authWithCustomToken(AUTH_TOKEN, new Firebase.AuthResultHandler() {
#Override
public void onAuthenticationError(FirebaseError error) {
System.err.println("Login Failed! " + error.getMessage());
}
#Override
public void onAuthenticated(AuthData authData) {
// authenticated
}
});
You probably aren't thrilled about having to run a server, but take a look at using Google AppEngine with the Firebase JVM client. It's pretty easy and handles the server maintenance for you.
This tutorial by a former Google Cloud tools member, and current Firebase team member is a great place to start.

Spring Social Facebook

I am developing with Spring Social and Thymeleaf from the quick start example, but I realised that it only supports one Facebook object per controller. This means the sample can't provide support for multiple users and I am guessing it has to do with the #Scope of the variable. Its runs in a Spring boot container and I wonder how I can configure this so that each session has its own Facebook object.
As you suggested, the Facebook object should be configured with request scope. If you're using the configuration support and/or Spring Boot, then it will be request scoped. Therefore, even though the controller is injected once with a Facebook instance, that instance is really a proxy that will delegate to a real FacebookTemplate instance that is created at request time for the authenticated user.
I can only assume that you're referring to the getting started guide example at http://spring.io/guides/gs/accessing-facebook/. In that case, it's using the most simple Spring Boot autoconfiguration possible for Spring Social, which includes a basic (yet not intended for production) implementation of UserIdSource which always returns "anonymous" as the user ID. Therefore, after you create the first Facebook connection, the second browser tries to find a connection for "anonymous", finds it, and gives you an authorized Facebook object.
This may seem peculiar, but it is an example app intended to get you started...and it does that. All you need to do to get a real UserIdSource is to add Spring Security to the project. That will tell Spring Social autoconfiguration to configure a UserIdSource that fetches the current user ID from the security context. This reflects a more real-world use of Spring Social, albeit obviously more involved and beyond the scope of the getting started guide.
But you can look at https://github.com/spring-projects/spring-social-samples/tree/master/spring-social-showcase-boot for a more complete example of Spring Social within Spring Boot.
Spring Boot autoconfigures a lot of things behind the scenes. It does autoconfigure the Facebook, LinkedIn and Twitter properties and sets up the connection factories for social providers.
However, the implementation of UserIdSource always returns “anonymous” as the user ID. Once the first Facebook connection is established the second browser will try to find a connection for “anonymous” which it finds and gives you an authorised Facebook object.
#Configuration
#EnableSocial
#ConditionalOnWebApplication
#ConditionalOnMissingClass("org.springframework.security.core.context.SecurityContextHolder")
protected static class AnonymousUserIdSourceConfig extends SocialConfigurerAdapter {
#Override
public UserIdSource getUserIdSource() {
return new UserIdSource() {
#Override
public String getUserId() {
return "anonymous";
}
};
}
}
Solution
The solution is to override the “anonymous” as the UserId for each new user/session. So for each session, we can simply return a SessionID, however, it may not be unique enough to identify users, especially if it’s being cached or stored somewhere in a connection database.
#Override
public String getUserId() {
RequestAttributes request = RequestContextHolder.currentRequestAttributes();
String uuid = (String) request.getAttribute("_socialUserUUID", RequestAttributes.SCOPE_SESSION);
if (uuid == null) {
uuid = UUID.randomUUID().toString();
request.setAttribute("_socialUserUUID", uuid, RequestAttributes.SCOPE_SESSION);
}
return uuid;
}
The solution for above problem has been talked about in detail over here

Security for Flex app when ssl is not available

So I know the best practice would be to run my Flex app over ssl along with implementing other forms of security however that isn't an option at this point (for monetary reasons and the app simply doesn't need that much security otherwise my sponsors would pay for it). However, I would like to implement some form of security and I'm wondering whether it's even worth it when I don't have ssl to protect the transactions.
So my setup is that I have a ASP.Net server side with a Flex UI. Right now the UI is the only thing that protects access to the sever: the server doesn't do any sort of verification during each request, it just assumes the person is allowed to do it. Obviously, anybody could write a program to generate posts (even if I could use SSL it would be like swiss cheese). Like I said before, security isn't a big deal, this is an internal app and it's nothing critical, however I do believe in doing things right. Would keeping the user info in session be a viable option and then verifying that the given user has permission, etc. Perhaps some sort of token system?
What would your preferred method of protecting this setup be?
...and no, I won't give you the url :)
ASP.NET Session itself is token based security and yes you can easily implement that by doing
[WebMethod(true)]
and yes, any web method requires login to be done first, it should call User.IsAuthenticated, that verifies the session token.
You can easily implement form authentication (let web.config empty, you can use FormsAuthentication in code).
for example,
[WebMethod(true)]
public string DoLogin(
string username,
string password)
{
//.. do your verification
FormsAuthentication.SetAuthCookie(username,false);
return "Login Sucessful";
}
[WebMethod(true)]
public string ChangePassword(
string oldPass,
string newPass)
{
// verify user is logged on or not..
if(!User.IsAuthenticated)
return "Please Login";
// The code below is secure, only
// authenticated user will go through below
// change pass...
return "Password Changed Successfully.";
}
We developed many Flex+ASP.NET sites, we did exactly same thing, but instead of return "string" we usually return a class like following...
public class WSResult<T>{
public bool Successful;
public string Message;
public T Result;
public T[] Results;
}
The convention is simple, if method was successful then you return Success = true, and depending upon whether you want to return an array of items or just single item, you can return either Results or Result. In case if there has been any error or unathorized access you can set Successful=false and set Message as detailed string. As per following example.
[WebMethod(true)]
public WSResult<BusinessUser> DoLogin(
string username,
string password)
{
try{
BusinessUser user = BusinessUser.GetByUsername(username);
if(user==null)
throw new Exception("User not found");
if(user.Password != password)
throw new Exception("Password did not match");
return new WSResult<BusinessUser>{ Result=user };
}catch(Exception ex)
{
// this will even catch any DAL exceptions or any system error as well
// Log Exception... somewhere for tracking...
return new WSResult<BusinessUser>{ Successful=false, Message = ex.Message };
}
}
Unfortunately, I know diddly squat about flex, but I think I can help anyway. I think you have two reasonably good options.
First though, we need to clarify something... Are you saying the server doesn't do any authorization? Does it at least have the ability to authenticate a user? Do you have any control over the server code? If not, I don't think the following suggestions will help. I'm not sure how you're supposed to secure a server with just client side code. Maybe there is a way, but I can't think of it.
1) Use HTTP digest authentication. This requires that the server is configured to understand it and that there is support in the flex api for adding the appropriate auth header to the HTTP request. The server authenticates the user by his password and can check what operations can be performed by said user against some authorization mechanism.
2) Follow the guidelines in this article to implement the authentication scheme that many atom publishing endpoints use. The flex api will have to provide some support for this, maybe there is an existing third party lib though. If you can get access to the HTTP headers you should be able to implement the rest.
Good luck.
How are you commuicating with the server SOAP. REST etc?
If it is SOAP have a look at the answer to this question
General Password Security && Implementation in Actionscript 3
and here's a link how to add the header to the SOAP message
How to add a "flat" message header to a flex web service call?
Hope this helps
Jon

Resources