Как ограничить доступ к определенной странице только 1 зарегистрированному пользователю? - PullRequest
0 голосов
/ 25 ноября 2018

Я делаю простой сайт для социальных сетей, используя Java Spring Boot.Теперь я хочу добавить страницу редактирования профиля, где зарегистрированный пользователь может редактировать / обновлять данные своего профиля, но другие зарегистрированные пользователи не должны иметь к нему доступ.

Например, есть два человека: Джон и Том, Джон должен видеть только страницу редактирования своего профиля, а Том должен видеть только свою страницу редактирования профиля Только после входа в систему.

Как добитьсяэто с помощью Spring Security или любым другим способом?

1 Ответ

0 голосов
/ 25 ноября 2018

Прежде всего вам нужно написать BeanAccessor, как показано ниже:

@Component
public class BeanAccessor implements ApplicationContextAware {

    private static ApplicationContext context;

    public static ObjectMapper getObjectMapper() {
        return getBean(ObjectMapper.class);
    }

    public static <T> T getBean(Class<T> beanClass, Object... args) {
        return context.getBean(beanClass, args);
    }

    private static <T> T getBean(Class<T> beanClass) {
        return context.getBean(beanClass);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }
}

, затем нам нужно написать новый класс для обеспечения безопасности метода, например:

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class CustomMethodSecurityExpressionRoot extends SecurityExpressionRoot implements MethodSecurityExpressionOperations {

    private Object filterObject;

    private Object returnObject;

    private Object target;

    public CustomMethodSecurityExpressionRoot(Authentication authentication) {
        super(authentication);
    }

    CustomMethodSecurityExpressionRoot setTarget(Object target) {
        this.target = target;
        return this;
    }

    @Override
    public void setFilterObject(Object filterObject) {
        this.filterObject = filterObject;
    }

    @Override
    public Object getFilterObject() {
        return filterObject;
    }

    @Override
    public void setReturnObject(Object returnObject) {
        this.returnObject = returnObject;
    }

    @Override
    public Object getReturnObject() {
        return returnObject;
    }

    @Override
    public Object getThis() {
        return target;
    }

}

наконец, нам нужны пользовательскиеобработчик выражения безопасности метода:

@Component
public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {

    @Autowired
    private CustomPermissionEvaluator customPermissionEvaluator;

    private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();

    @Override
    protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) {
        final CustomMethodSecurityExpressionRoot root = BeanAccessor.getBean(CustomMethodSecurityExpressionRoot.class, authentication);
        root.setPermissionEvaluator(customPermissionEvaluator);
        root.setTrustResolver(this.trustResolver);
        root.setRoleHierarchy(getRoleHierarchy());
        root.setTarget(invocation.getThis());
        return root;
    }

}

теперь в вашем контроллере метод yo может определять @PreAuthorize("isProfileOwner(#id)") аннотации, которые ваш метод отображения страницы профиля пользователя выглядит следующим образом:

@PreAuthorize("isProfileOwner(#id)")
@GetMapping("{id}")
public String show(@PathVariable("id") Long id, Model model) {
//omitted
}

все в порядке, но нам нужнонапишите isProfileOwner() метод в наш CustomMethodSecurityExpressionRoot класс, например:

public boolean isProfileOwner(Long id) {
//add logic here and you are ready
}

, также вы можете проверить это post

...