What is Permission Management

Authority management has been imperceptibly deep into every corner of our lives, such as the subway station gate machine, highway toll, parking levers and so on.

As a developer, the rights of two words on our image is more profound, no matter any system, more or less with the rights management will touch the relationship! What? Your system and permissions are irrelevant…… Well, your code pull permission must have! If you haven’t already, you go to the Nuggets and see this article and click a “like” which requires multiple permissions checks. Anyway, back to the point, here’s a simple illustration of what web system permissions look like:

After reading, does it feel very simple, good, permission management is not difficult, we just need to check this link to develop, there are many ways to achieve:

Solution 1: Encapsulate components

We can componentize the whole process of permission verification, for example, the component is named AuthComponent, and then call the verify method of AuthComponent at the beginning of the corresponding method of all the interfaces that need permission verification, and do different business processing according to the result!

  • Pros: Seems to achieve the main goal and is very flexible
  • Cons: Code redundancy, low cohesion, high coupling, not easy to maintain.

Solution 2: General treatment

For example, using AOP to make an aspect of the interface that needs to be verified, we can use AuthComponent to verify the method before execution, so that our code is more maintainable!

  • Advantages: make up for the shortcomings of scheme 1.
  • Disadvantages: Too general, difficult to be compatible with all cases, not flexible.

Option 3: Customize annotations

Let’s combine solution 1 with solution 2, take one as flexible, take two as generic, let’s define a custom annotation named @auth, and it needs to pass a parameter, we define the diameter of the enumeration class Level, the simple structure is as follows:

public enum Level { LOGIN, ADMIN }
Copy the code

We then define an annotation section that tangents to the @auth method and manages different permissions based on the value of the value, i.e. the value of Level, before the method executes.

  • Advantages: flexible and controllable, generality.
  • Disadvantages: Lack of componentization, fragmented structure, not easy to reuse, for a variety of scenarios need to develop multiple sections, not elegant!

Option 4: Use a framework

This is the simplest approach, such as excellent open source Shiro, Spring-Security, etc., can meet our needs, the only difference is the weight of the framework and how to use it!

How to manage permissions more gracefully

Presumably, many students are using the fourth plan, and many partners are using the third plan. For the obvious shortcomings of the first and second plan, the use should be very few.

What if our services don’t need a heavy rights management framework to solve the rights problem, but don’t want to implement inelegant custom annotations?

Try Defender

What is the Defender

Defender is a lightweight, highly flexible, and highly available privilege framework that fully embraces Spring-Boot. If we need to add more elegant rights management to the service in daily life, then Defender is just right for us!

It frees us from repeatedly writing custom annotations and facets, and allows us to flexibly specify different patterns of defense networks with simple API calls.

Why grace

Defender provides a small and flexible API to specify the permissions filtering network you want. Defender provides a variety of defense modes. We can quickly manage permissions by calling a simple API that uses validators that build different modes:

@Configuration
@EnableDefender("* org.nico.trap.controller.. *. * (..) ")
public class DefenderTestConfig {
	@Bean
	public Defender init() {return Defender.getInstance()
				.registry(Guarder.builder(GuarderType.URI)
						.pattern("POST /user/*")
						.preventer(caller- > {return caller.getRequest().getHeader("token") == null 
								? Result.pass() : Result.notpass("error"); })) .ready(); }}Copy the code

This code manages permissions for all interfaces whose requests match the POST type and whose URI prefix is /user/.

In addition, we can use lambda for simple permission verification logic, or use anonymous classes for complex verification logic:

Guarder.builder(GuarderType.ANNOTATION)
		.pattern("org.nico.trap.controller")
		.preventer(new AbstractPreventer() {
			
			@Autowired
			private AuthComponent authComponent;
			
			@Override
			public Result detection(Caller caller) {
				String identity = caller.getAccess().value();
				if(! identity.equals(AuthConst.VISITOR)) {
					UserBo user = authComponent.getUser();
					if(user ! = null) {if(identity.equals(AuthConst.ADMIN)){
							if(user.getRuleType() == null) {
								returnResult.notpass(new ResponseVo<>(ResponseCode.ERROR_ON_USER_IDENTITY_MISMATCH)); }}}else {
						returnResult.notpass(new ResponseVo<>(ResponseCode.ERROR_ON_LOGIN_INVALID)); }}returnResult.pass(); }})Copy the code

URI and GuarderType.ANNOTATION respectively represent URI ANT matching mode and ANNOTATION mode. The latter is the implementation of Solution 3. Defender provides simple and elegant API to aggregate the permission verification modes of various modes.

Defender is lighter and more flexible than Shiro and Spring-Security, because it does not provide a more specific set of permissions management implementations. Instead, it opens the validation implementation to developers as an interface. The overall code size is 21K. Defender is more suitable!

Various portals

Defender is just getting started, so if you’re interested you can integrate it into your development environment. The project is located below

Defender portal

Official also provides a simple use of documentation

Chinese document

English Document

If you feel good and want to contribute

How to contribute